This source file includes following definitions.
- DispatchEventDuringScrollCallback
- ChangeSliderOwnerDuringScrollCallback
- ConfirmSlideDuringScrollCallback
- ConfirmNoSlideDuringScrollCallback
- HasHitTestMask
- slider_destroyed_
- Reset
- SetCanCreateLayer
- created_back_layer
- created_front_layer
- slide_completing
- slide_completed
- slide_aborted
- slider_destroyed
- CreateLayerForTest
- CreateBackLayer
- CreateFrontLayer
- OnWindowSlideCompleted
- OnWindowSlideCompleting
- OnWindowSlideAborted
- OnWindowSliderDestroyed
- OnWindowSliderDestroyed
- OnWindowSlideCompleted
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "content/browser/web_contents/aura/window_slider.h"
#include "base/bind.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/compositor/test/layer_animator_test_controller.h"
#include "ui/events/event_processor.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/frame_time.h"
namespace content {
void DispatchEventDuringScrollCallback(ui::EventProcessor* dispatcher,
ui::Event* event,
ui::EventType type,
const gfx::Vector2dF& delta) {
if (type != ui::ET_GESTURE_SCROLL_UPDATE)
return;
ui::EventDispatchDetails details = dispatcher->OnEventFromSource(event);
CHECK(!details.dispatcher_destroyed);
}
void ChangeSliderOwnerDuringScrollCallback(scoped_ptr<aura::Window>* window,
WindowSlider* slider,
ui::EventType type,
const gfx::Vector2dF& delta) {
if (type != ui::ET_GESTURE_SCROLL_UPDATE)
return;
aura::Window* new_window = new aura::Window(NULL);
new_window->Init(aura::WINDOW_LAYER_TEXTURED);
new_window->Show();
slider->ChangeOwner(new_window);
(*window)->parent()->AddChild(new_window);
window->reset(new_window);
}
void ConfirmSlideDuringScrollCallback(WindowSlider* slider,
ui::EventType type,
const gfx::Vector2dF& delta) {
static float total_delta_x = 0;
if (type == ui::ET_GESTURE_SCROLL_BEGIN)
total_delta_x = 0;
if (type == ui::ET_GESTURE_SCROLL_UPDATE) {
total_delta_x += delta.x();
if (total_delta_x >= 70)
EXPECT_TRUE(slider->IsSlideInProgress());
} else {
EXPECT_FALSE(slider->IsSlideInProgress());
}
}
void ConfirmNoSlideDuringScrollCallback(WindowSlider* slider,
ui::EventType type,
const gfx::Vector2dF& delta) {
EXPECT_FALSE(slider->IsSlideInProgress());
}
class NoEventWindowDelegate : public aura::test::TestWindowDelegate {
public:
NoEventWindowDelegate() {
}
virtual ~NoEventWindowDelegate() {}
private:
virtual bool HasHitTestMask() const OVERRIDE { return true; }
DISALLOW_COPY_AND_ASSIGN(NoEventWindowDelegate);
};
class WindowSliderDelegateTest : public WindowSlider::Delegate {
public:
WindowSliderDelegateTest()
: can_create_layer_(true),
created_back_layer_(false),
created_front_layer_(false),
slide_completing_(false),
slide_completed_(false),
slide_aborted_(false),
slider_destroyed_(false) {
}
virtual ~WindowSliderDelegateTest() {
CHECK(!slide_completing_ || slide_completed_);
}
void Reset() {
can_create_layer_ = true;
created_back_layer_ = false;
created_front_layer_ = false;
slide_completing_ = false;
slide_completed_ = false;
slide_aborted_ = false;
slider_destroyed_ = false;
}
void SetCanCreateLayer(bool can_create_layer) {
can_create_layer_ = can_create_layer;
}
bool created_back_layer() const { return created_back_layer_; }
bool created_front_layer() const { return created_front_layer_; }
bool slide_completing() const { return slide_completing_; }
bool slide_completed() const { return slide_completed_; }
bool slide_aborted() const { return slide_aborted_; }
bool slider_destroyed() const { return slider_destroyed_; }
protected:
ui::Layer* CreateLayerForTest() {
CHECK(can_create_layer_);
ui::Layer* layer = new ui::Layer(ui::LAYER_SOLID_COLOR);
layer->SetColor(SK_ColorRED);
return layer;
}
virtual ui::Layer* CreateBackLayer() OVERRIDE {
if (!can_create_layer_)
return NULL;
created_back_layer_ = true;
return CreateLayerForTest();
}
virtual ui::Layer* CreateFrontLayer() OVERRIDE {
if (!can_create_layer_)
return NULL;
created_front_layer_ = true;
return CreateLayerForTest();
}
virtual void OnWindowSlideCompleted() OVERRIDE {
slide_completed_ = true;
}
virtual void OnWindowSlideCompleting() OVERRIDE {
slide_completing_ = true;
}
virtual void OnWindowSlideAborted() OVERRIDE {
slide_aborted_ = true;
}
virtual void OnWindowSliderDestroyed() OVERRIDE {
slider_destroyed_ = true;
}
private:
bool can_create_layer_;
bool created_back_layer_;
bool created_front_layer_;
bool slide_completing_;
bool slide_completed_;
bool slide_aborted_;
bool slider_destroyed_;
DISALLOW_COPY_AND_ASSIGN(WindowSliderDelegateTest);
};
class WindowSliderDeleteOwnerOnDestroy : public WindowSliderDelegateTest {
public:
explicit WindowSliderDeleteOwnerOnDestroy(aura::Window* owner)
: owner_(owner) {
}
virtual ~WindowSliderDeleteOwnerOnDestroy() {}
private:
virtual void OnWindowSliderDestroyed() OVERRIDE {
WindowSliderDelegateTest::OnWindowSliderDestroyed();
delete owner_;
}
aura::Window* owner_;
DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnDestroy);
};
class WindowSliderDeleteOwnerOnComplete : public WindowSliderDelegateTest {
public:
explicit WindowSliderDeleteOwnerOnComplete(aura::Window* owner)
: owner_(owner) {
}
virtual ~WindowSliderDeleteOwnerOnComplete() {}
private:
virtual void OnWindowSlideCompleted() OVERRIDE {
WindowSliderDelegateTest::OnWindowSlideCompleted();
delete owner_;
}
aura::Window* owner_;
DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnComplete);
};
typedef aura::test::AuraTestBase WindowSliderTest;
TEST_F(WindowSliderTest, WindowSlideUsingGesture) {
scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
window->SetBounds(gfx::Rect(0, 0, 400, 400));
WindowSliderDelegateTest slider_delegate;
aura::test::EventGenerator generator(root_window());
WindowSlider* slider =
new WindowSlider(&slider_delegate, root_window(), window.get());
generator.GestureScrollSequenceWithCallback(
gfx::Point(10, 10),
gfx::Point(180, 10),
base::TimeDelta::FromMilliseconds(10),
10,
base::Bind(&ConfirmSlideDuringScrollCallback, slider));
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.slider_destroyed());
EXPECT_FALSE(slider->IsSlideInProgress());
slider_delegate.Reset();
window->SetTransform(gfx::Transform());
generator.GestureScrollSequenceWithCallback(
gfx::Point(180, 10),
gfx::Point(10, 10),
base::TimeDelta::FromMilliseconds(10),
10,
base::Bind(&ConfirmSlideDuringScrollCallback, slider));
EXPECT_TRUE(slider_delegate.created_front_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_back_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.slider_destroyed());
EXPECT_FALSE(slider->IsSlideInProgress());
slider_delegate.Reset();
generator.GestureScrollSequenceWithCallback(
gfx::Point(10, 10),
gfx::Point(10, 80),
base::TimeDelta::FromMilliseconds(10),
10,
base::Bind(&ConfirmNoSlideDuringScrollCallback, slider));
EXPECT_FALSE(slider_delegate.created_back_layer());
EXPECT_FALSE(slider_delegate.slide_completing());
EXPECT_FALSE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider->IsSlideInProgress());
slider_delegate.Reset();
generator.GestureScrollSequenceWithCallback(
gfx::Point(10, 10),
gfx::Point(80, 10),
base::TimeDelta::FromMilliseconds(10),
10,
base::Bind(&ConfirmSlideDuringScrollCallback, slider));
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_completing());
EXPECT_FALSE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.slider_destroyed());
EXPECT_FALSE(slider->IsSlideInProgress());
slider_delegate.Reset();
window.reset();
EXPECT_TRUE(slider_delegate.slider_destroyed());
}
TEST_F(WindowSliderTest, WindowSlideIsCancelledOnEvent) {
scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
window->SetBounds(gfx::Rect(0, 0, 400, 400));
WindowSliderDelegateTest slider_delegate;
ui::Event* events[] = {
new ui::MouseEvent(ui::ET_MOUSE_MOVED,
gfx::Point(55, 10),
gfx::Point(55, 10),
0, 0),
new ui::KeyEvent(ui::ET_KEY_PRESSED,
ui::VKEY_A,
0,
true),
NULL
};
new WindowSlider(&slider_delegate, root_window(), window.get());
for (int i = 0; events[i]; ++i) {
aura::test::EventGenerator generator(root_window());
generator.GestureScrollSequenceWithCallback(
gfx::Point(10, 10),
gfx::Point(80, 10),
base::TimeDelta::FromMilliseconds(10),
1,
base::Bind(&DispatchEventDuringScrollCallback,
root_window()->GetHost()->event_processor(),
base::Owned(events[i])));
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_completing());
EXPECT_FALSE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.slider_destroyed());
slider_delegate.Reset();
}
window.reset();
EXPECT_TRUE(slider_delegate.slider_destroyed());
}
TEST_F(WindowSliderTest, WindowSlideInterruptedThenContinues) {
scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
window->SetBounds(gfx::Rect(0, 0, 400, 400));
WindowSliderDelegateTest slider_delegate;
ui::ScopedAnimationDurationScaleMode normal_duration_(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ui::LayerAnimator* animator = window->layer()->GetAnimator();
gfx::AnimationContainerElement* element = animator;
animator->set_disable_timer_for_test(true);
ui::LayerAnimatorTestController test_controller(animator);
WindowSlider* slider =
new WindowSlider(&slider_delegate, root_window(), window.get());
ui::MouseEvent interrupt_event(ui::ET_MOUSE_MOVED,
gfx::Point(55, 10),
gfx::Point(55, 10),
0, 0);
aura::test::EventGenerator generator(root_window());
const int kTouchId = 5;
ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
gfx::Point(10, 10),
kTouchId,
ui::EventTimeForNow());
generator.Dispatch(&press);
ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
gfx::Point(100, 10),
kTouchId,
ui::EventTimeForNow());
generator.Dispatch(&move1);
EXPECT_TRUE(slider->IsSlideInProgress());
EXPECT_FALSE(animator->is_animating());
generator.Dispatch(&interrupt_event);
EXPECT_TRUE(slider->IsSlideInProgress());
EXPECT_TRUE(animator->is_animating());
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_completing());
EXPECT_FALSE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.slider_destroyed());
slider_delegate.Reset();
ui::TouchEvent move2(ui::ET_TOUCH_MOVED,
gfx::Point(200, 10),
kTouchId,
ui::EventTimeForNow());
generator.Dispatch(&move2);
EXPECT_FALSE(animator->is_animating());
EXPECT_FALSE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_aborted());
ui::TouchEvent move3(ui::ET_TOUCH_MOVED,
gfx::Point(300, 10),
kTouchId,
ui::EventTimeForNow());
generator.Dispatch(&move3);
EXPECT_TRUE(slider->IsSlideInProgress());
EXPECT_TRUE(slider_delegate.created_back_layer());
ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
gfx::Point(300, 10),
kTouchId,
ui::EventTimeForNow());
generator.Dispatch(&release);
EXPECT_TRUE(slider->IsSlideInProgress());
EXPECT_TRUE(animator->is_animating());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.slider_destroyed());
ui::ScopedLayerAnimationSettings settings(animator);
base::TimeDelta duration = settings.GetTransitionDuration();
test_controller.StartThreadedAnimationsIfNeeded();
element->Step(gfx::FrameTime::Now() + duration);
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.slider_destroyed());
window.reset();
EXPECT_TRUE(slider_delegate.slider_destroyed());
}
TEST_F(WindowSliderTest, OwnerWindowChangesDuringWindowSlide) {
scoped_ptr<aura::Window> parent(CreateNormalWindow(0, root_window(), NULL));
NoEventWindowDelegate window_delegate;
window_delegate.set_window_component(HTNOWHERE);
scoped_ptr<aura::Window> window(CreateNormalWindow(1, parent.get(),
&window_delegate));
WindowSliderDelegateTest slider_delegate;
scoped_ptr<WindowSlider> slider(
new WindowSlider(&slider_delegate, parent.get(), window.get()));
aura::test::EventGenerator generator(root_window());
aura::Window* old_window = window.get();
generator.GestureScrollSequenceWithCallback(
gfx::Point(10, 10),
gfx::Point(80, 10),
base::TimeDelta::FromMilliseconds(10),
1,
base::Bind(&ChangeSliderOwnerDuringScrollCallback,
base::Unretained(&window),
slider.get()));
aura::Window* new_window = window.get();
EXPECT_NE(old_window, new_window);
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.slider_destroyed());
}
TEST_F(WindowSliderTest, NoSlideWhenLayerCantBeCreated) {
scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
window->SetBounds(gfx::Rect(0, 0, 400, 400));
WindowSliderDelegateTest slider_delegate;
slider_delegate.SetCanCreateLayer(false);
WindowSlider* slider =
new WindowSlider(&slider_delegate, root_window(), window.get());
aura::test::EventGenerator generator(root_window());
generator.GestureScrollSequenceWithCallback(
gfx::Point(10, 10),
gfx::Point(180, 10),
base::TimeDelta::FromMilliseconds(10),
1,
base::Bind(&ConfirmNoSlideDuringScrollCallback, slider));
EXPECT_FALSE(slider_delegate.created_back_layer());
EXPECT_FALSE(slider_delegate.slide_completing());
EXPECT_FALSE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.slider_destroyed());
window->SetTransform(gfx::Transform());
slider_delegate.SetCanCreateLayer(true);
generator.GestureScrollSequenceWithCallback(
gfx::Point(10, 10),
gfx::Point(180, 10),
base::TimeDelta::FromMilliseconds(10),
10,
base::Bind(&ConfirmSlideDuringScrollCallback, slider));
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.slider_destroyed());
window.reset();
EXPECT_TRUE(slider_delegate.slider_destroyed());
}
TEST_F(WindowSliderTest, OwnerIsDestroyedOnSliderDestroy) {
size_t child_windows = root_window()->children().size();
aura::Window* window = CreateNormalWindow(0, root_window(), NULL);
window->SetBounds(gfx::Rect(0, 0, 400, 400));
EXPECT_EQ(child_windows + 1, root_window()->children().size());
WindowSliderDeleteOwnerOnDestroy slider_delegate(window);
aura::test::EventGenerator generator(root_window());
scoped_ptr<WindowSlider> slider(
new WindowSlider(&slider_delegate, root_window(), window));
generator.GestureScrollSequence(gfx::Point(10, 10),
gfx::Point(180, 10),
base::TimeDelta::FromMilliseconds(10),
10);
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.slider_destroyed());
slider.reset();
EXPECT_EQ(child_windows, root_window()->children().size());
}
TEST_F(WindowSliderTest, OwnerIsDestroyedOnSlideComplete) {
size_t child_windows = root_window()->children().size();
aura::Window* window = CreateNormalWindow(0, root_window(), NULL);
window->SetBounds(gfx::Rect(0, 0, 400, 400));
EXPECT_EQ(child_windows + 1, root_window()->children().size());
WindowSliderDeleteOwnerOnComplete slider_delegate(window);
aura::test::EventGenerator generator(root_window());
new WindowSlider(&slider_delegate, root_window(), window);
generator.GestureScrollSequence(gfx::Point(10, 10),
gfx::Point(180, 10),
base::TimeDelta::FromMilliseconds(10),
10);
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_TRUE(slider_delegate.slider_destroyed());
EXPECT_EQ(child_windows, root_window()->children().size());
}
TEST_F(WindowSliderTest, SwipeDuringSwipeAnimation) {
scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
window->SetBounds(gfx::Rect(0, 0, 400, 400));
WindowSliderDelegateTest slider_delegate;
new WindowSlider(&slider_delegate, root_window(), window.get());
ui::ScopedAnimationDurationScaleMode normal_duration_(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ui::LayerAnimator* animator = window->layer()->GetAnimator();
gfx::AnimationContainerElement* element = animator;
animator->set_disable_timer_for_test(true);
ui::LayerAnimatorTestController test_controller(animator);
aura::test::EventGenerator generator(root_window());
generator.GestureScrollSequence(
gfx::Point(10, 10),
gfx::Point(180, 10),
base::TimeDelta::FromMilliseconds(10),
2);
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_FALSE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.slider_destroyed());
ui::ScopedLayerAnimationSettings settings(animator);
base::TimeDelta duration = settings.GetTransitionDuration();
test_controller.StartThreadedAnimationsIfNeeded();
base::TimeTicks start_time1 = gfx::FrameTime::Now();
element->Step(start_time1 + duration/2);
EXPECT_FALSE(slider_delegate.slide_completed());
slider_delegate.Reset();
generator.GestureScrollSequence(
gfx::Point(10, 10),
gfx::Point(180, 10),
base::TimeDelta::FromMilliseconds(10),
2);
EXPECT_TRUE(slider_delegate.created_back_layer());
EXPECT_FALSE(slider_delegate.slide_aborted());
EXPECT_FALSE(slider_delegate.created_front_layer());
EXPECT_TRUE(slider_delegate.slide_completing());
EXPECT_TRUE(slider_delegate.slide_completed());
EXPECT_FALSE(slider_delegate.slider_destroyed());
test_controller.StartThreadedAnimationsIfNeeded();
base::TimeTicks start_time2 = gfx::FrameTime::Now();
slider_delegate.Reset();
element->Step(start_time2 + duration);
EXPECT_TRUE(slider_delegate.slide_completed());
slider_delegate.Reset();
window.reset();
EXPECT_TRUE(slider_delegate.slider_destroyed());
}
}