File: capture_controller_unittest.cc

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (199 lines) | stat: -rw-r--r-- 7,461 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Copyright (c) 2013 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 "ui/wm/core/capture_controller.h"

#include "base/logging.h"
#include "ui/aura/client/capture_delegate.h"
#include "ui/aura/env.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"

namespace wm {

namespace {

// aura::client::CaptureDelegate which allows querying whether native capture
// has been acquired.
class TestCaptureDelegate : public aura::client::CaptureDelegate {
 public:
  TestCaptureDelegate() : has_capture_(false) {}
  ~TestCaptureDelegate() override {}

  bool HasNativeCapture() const {
    return has_capture_;
  }

  // aura::client::CaptureDelegate:
  void UpdateCapture(aura::Window* old_capture,
                     aura::Window* new_capture) override {}
  void OnOtherRootGotCapture() override {}
  void SetNativeCapture() override { has_capture_ = true; }
  void ReleaseNativeCapture() override { has_capture_ = false; }

 private:
  bool has_capture_;

  DISALLOW_COPY_AND_ASSIGN(TestCaptureDelegate);
};

}  // namespace

class CaptureControllerTest : public aura::test::AuraTestBase {
 public:
  CaptureControllerTest() {}

  void SetUp() override {
    AuraTestBase::SetUp();
    capture_controller_.reset(new ScopedCaptureClient(root_window()));

    second_host_.reset(aura::WindowTreeHost::Create(gfx::Rect(0, 0, 800, 600)));
    second_host_->InitHost();
    second_host_->window()->Show();
    second_host_->SetBounds(gfx::Rect(800, 600));
    second_capture_controller_.reset(
        new ScopedCaptureClient(second_host_->window()));
  }

  void TearDown() override {
    RunAllPendingInMessageLoop();

    second_capture_controller_.reset();

    // Kill any active compositors before we hit the compositor shutdown paths.
    second_host_.reset();

    capture_controller_.reset();

    AuraTestBase::TearDown();
  }

  aura::Window* GetCaptureWindow() {
    return capture_controller_->capture_client()->GetCaptureWindow();
  }

  aura::Window* GetSecondCaptureWindow() {
    return second_capture_controller_->capture_client()->GetCaptureWindow();
  }

  scoped_ptr<ScopedCaptureClient> capture_controller_;
  scoped_ptr<aura::WindowTreeHost> second_host_;
  scoped_ptr<ScopedCaptureClient> second_capture_controller_;

  DISALLOW_COPY_AND_ASSIGN(CaptureControllerTest);
};

// Makes sure that internal details that are set on mouse down (such as
// mouse_pressed_handler()) are cleared when another root window takes capture.
TEST_F(CaptureControllerTest, ResetMouseEventHandlerOnCapture) {
  // Create a window inside the WindowEventDispatcher.
  scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL));

  // Make a synthesized mouse down event. Ensure that the WindowEventDispatcher
  // will dispatch further mouse events to |w1|.
  ui::MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5),
                                     gfx::Point(5, 5), 0, 0);
  DispatchEventUsingWindowDispatcher(&mouse_pressed_event);
  EXPECT_EQ(w1.get(), host()->dispatcher()->mouse_pressed_handler());

  // Build a window in the second WindowEventDispatcher.
  scoped_ptr<aura::Window> w2(
      CreateNormalWindow(2, second_host_->window(), NULL));

  // The act of having the second window take capture should clear out mouse
  // pressed handler in the first WindowEventDispatcher.
  w2->SetCapture();
  EXPECT_EQ(NULL, host()->dispatcher()->mouse_pressed_handler());
}

// Makes sure that when one window gets capture, it forces the release on the
// other. This is needed has to be handled explicitly on Linux, and is a sanity
// check on Windows.
TEST_F(CaptureControllerTest, ResetOtherWindowCaptureOnCapture) {
  // Create a window inside the WindowEventDispatcher.
  scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL));
  w1->SetCapture();
  // Both capture clients should return the same capture window.
  EXPECT_EQ(w1.get(), GetCaptureWindow());
  EXPECT_EQ(w1.get(), GetSecondCaptureWindow());

  // Build a window in the second WindowEventDispatcher and give it capture.
  // Both capture clients should return the same capture window.
  scoped_ptr<aura::Window> w2(
      CreateNormalWindow(2, second_host_->window(), NULL));
  w2->SetCapture();
  EXPECT_EQ(w2.get(), GetCaptureWindow());
  EXPECT_EQ(w2.get(), GetSecondCaptureWindow());
}

// Verifies the touch target for the WindowEventDispatcher gets reset on
// releasing capture.
TEST_F(CaptureControllerTest, TouchTargetResetOnCaptureChange) {
  // Create a window inside the WindowEventDispatcher.
  scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL));
  ui::test::EventGenerator event_generator1(root_window());
  event_generator1.PressTouch();
  w1->SetCapture();
  // Both capture clients should return the same capture window.
  EXPECT_EQ(w1.get(), GetCaptureWindow());
  EXPECT_EQ(w1.get(), GetSecondCaptureWindow());

  // Build a window in the second WindowEventDispatcher and give it capture.
  // Both capture clients should return the same capture window.
  scoped_ptr<aura::Window> w2(
      CreateNormalWindow(2, second_host_->window(), NULL));
  w2->SetCapture();
  EXPECT_EQ(w2.get(), GetCaptureWindow());
  EXPECT_EQ(w2.get(), GetSecondCaptureWindow());

  // Release capture on the window. Releasing capture should reset the touch
  // target of the first WindowEventDispatcher (as it no longer contains the
  // capture target).
  w2->ReleaseCapture();
  EXPECT_EQ(static_cast<aura::Window*>(NULL), GetCaptureWindow());
  EXPECT_EQ(static_cast<aura::Window*>(NULL), GetSecondCaptureWindow());
  ui::TouchEvent touch_event(
      ui::ET_TOUCH_PRESSED, gfx::Point(), 0, 0, ui::EventTimeForNow(), 1.0f,
      1.0f, 1.0f, 1.0f);
  EXPECT_EQ(static_cast<ui::GestureConsumer*>(w2.get()),
            ui::GestureRecognizer::Get()->GetTouchLockedTarget(touch_event));
}

// Test that native capture is released properly when the window with capture
// is reparented to a different root window while it has capture.
TEST_F(CaptureControllerTest, ReparentedWhileCaptured) {
  scoped_ptr<TestCaptureDelegate> delegate(new TestCaptureDelegate);
  ScopedCaptureClient::TestApi(capture_controller_.get())
      .SetDelegate(delegate.get());
  scoped_ptr<TestCaptureDelegate> delegate2(new TestCaptureDelegate);
  ScopedCaptureClient::TestApi(second_capture_controller_.get())
      .SetDelegate(delegate2.get());

  scoped_ptr<aura::Window> w(CreateNormalWindow(1, root_window(), NULL));
  w->SetCapture();
  EXPECT_EQ(w.get(), GetCaptureWindow());
  EXPECT_EQ(w.get(), GetSecondCaptureWindow());
  EXPECT_TRUE(delegate->HasNativeCapture());
  EXPECT_FALSE(delegate2->HasNativeCapture());

  second_host_->window()->AddChild(w.get());
  EXPECT_EQ(w.get(), GetCaptureWindow());
  EXPECT_EQ(w.get(), GetSecondCaptureWindow());
  EXPECT_TRUE(delegate->HasNativeCapture());
  EXPECT_FALSE(delegate2->HasNativeCapture());

  w->ReleaseCapture();
  EXPECT_EQ(nullptr, GetCaptureWindow());
  EXPECT_EQ(nullptr, GetSecondCaptureWindow());
  EXPECT_FALSE(delegate->HasNativeCapture());
  EXPECT_FALSE(delegate2->HasNativeCapture());
}

}  // namespace wm