Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / display / chromeos / x11 / native_display_event_dispatcher_x11_unittest.cc
blobd7cf58926408b9ca825fcf550201a062956ebd7c
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
3 // found in the LICENSE file.
5 #include <X11/extensions/Xrandr.h>
7 #undef Bool
8 #undef None
10 #include "base/test/simple_test_tick_clock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/display/chromeos/x11/display_mode_x11.h"
13 #include "ui/display/chromeos/x11/display_snapshot_x11.h"
14 #include "ui/display/chromeos/x11/native_display_delegate_x11.h"
15 #include "ui/display/chromeos/x11/native_display_event_dispatcher_x11.h"
17 namespace ui {
19 namespace {
21 DisplaySnapshotX11* CreateOutput(RROutput output, RRCrtc crtc) {
22 static const DisplayModeX11* kDefaultDisplayMode =
23 new DisplayModeX11(gfx::Size(1, 1), false, 60.0f, 20);
25 DisplaySnapshotX11* snapshot = new DisplaySnapshotX11(
27 false,
28 gfx::Point(0, 0),
29 gfx::Size(0, 0),
30 DISPLAY_CONNECTION_TYPE_UNKNOWN,
31 false,
32 false,
33 std::string(),
34 std::vector<const DisplayMode*>(1, kDefaultDisplayMode),
35 kDefaultDisplayMode,
36 NULL,
37 output,
38 crtc,
39 0);
41 return snapshot;
44 class TestHelperDelegate : public NativeDisplayDelegateX11::HelperDelegate {
45 public:
46 TestHelperDelegate();
47 virtual ~TestHelperDelegate();
49 int num_calls_update_xrandr_config() const {
50 return num_calls_update_xrandr_config_;
53 int num_calls_notify_observers() const { return num_calls_notify_observers_; }
55 void set_cached_outputs(const std::vector<DisplaySnapshot*>& outputs) {
56 cached_outputs_ = outputs;
59 // NativeDisplayDelegateX11::HelperDelegate overrides:
60 virtual void UpdateXRandRConfiguration(const base::NativeEvent& event)
61 OVERRIDE;
62 virtual const std::vector<DisplaySnapshot*>& GetCachedDisplays() const
63 OVERRIDE;
64 virtual void NotifyDisplayObservers() OVERRIDE;
66 private:
67 int num_calls_update_xrandr_config_;
68 int num_calls_notify_observers_;
70 std::vector<DisplaySnapshot*> cached_outputs_;
72 DISALLOW_COPY_AND_ASSIGN(TestHelperDelegate);
75 TestHelperDelegate::TestHelperDelegate()
76 : num_calls_update_xrandr_config_(0), num_calls_notify_observers_(0) {}
78 TestHelperDelegate::~TestHelperDelegate() {}
80 void TestHelperDelegate::UpdateXRandRConfiguration(
81 const base::NativeEvent& event) {
82 ++num_calls_update_xrandr_config_;
85 const std::vector<DisplaySnapshot*>& TestHelperDelegate::GetCachedDisplays()
86 const {
87 return cached_outputs_;
90 void TestHelperDelegate::NotifyDisplayObservers() {
91 ++num_calls_notify_observers_;
94 ////////////////////////////////////////////////////////////////////////////////
95 // NativeDisplayEventDispatcherX11Test
97 class NativeDisplayEventDispatcherX11Test : public testing::Test {
98 public:
99 NativeDisplayEventDispatcherX11Test();
100 virtual ~NativeDisplayEventDispatcherX11Test();
102 protected:
103 void DispatchScreenChangeEvent();
104 void DispatchOutputChangeEvent(RROutput output,
105 RRCrtc crtc,
106 RRMode mode,
107 bool connected);
109 int xrandr_event_base_;
110 scoped_ptr<TestHelperDelegate> helper_delegate_;
111 scoped_ptr<NativeDisplayEventDispatcherX11> dispatcher_;
112 base::SimpleTestTickClock* test_tick_clock_; // Owned by |dispatcher_|.
114 private:
115 DISALLOW_COPY_AND_ASSIGN(NativeDisplayEventDispatcherX11Test);
118 NativeDisplayEventDispatcherX11Test::NativeDisplayEventDispatcherX11Test()
119 : xrandr_event_base_(10),
120 helper_delegate_(new TestHelperDelegate()),
121 dispatcher_(new NativeDisplayEventDispatcherX11(helper_delegate_.get(),
122 xrandr_event_base_)),
123 test_tick_clock_(new base::SimpleTestTickClock) {
124 test_tick_clock_->Advance(base::TimeDelta::FromMilliseconds(1));
125 dispatcher_->SetTickClockForTest(
126 scoped_ptr<base::TickClock>(test_tick_clock_));
129 NativeDisplayEventDispatcherX11Test::~NativeDisplayEventDispatcherX11Test() {}
131 void NativeDisplayEventDispatcherX11Test::DispatchScreenChangeEvent() {
132 XRRScreenChangeNotifyEvent event = {0};
133 event.type = xrandr_event_base_ + RRScreenChangeNotify;
135 dispatcher_->DispatchEvent(reinterpret_cast<const PlatformEvent>(&event));
138 void NativeDisplayEventDispatcherX11Test::DispatchOutputChangeEvent(
139 RROutput output,
140 RRCrtc crtc,
141 RRMode mode,
142 bool connected) {
143 XRROutputChangeNotifyEvent event = {0};
144 event.type = xrandr_event_base_ + RRNotify;
145 event.subtype = RRNotify_OutputChange;
146 event.output = output;
147 event.crtc = crtc;
148 event.mode = mode;
149 event.connection = connected ? RR_Connected : RR_Disconnected;
151 dispatcher_->DispatchEvent(reinterpret_cast<const PlatformEvent>(&event));
154 } // namespace
156 TEST_F(NativeDisplayEventDispatcherX11Test, OnScreenChangedEvent) {
157 DispatchScreenChangeEvent();
158 EXPECT_EQ(1, helper_delegate_->num_calls_update_xrandr_config());
159 EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
162 TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnFirstEvent) {
163 DispatchOutputChangeEvent(1, 10, 20, true);
164 EXPECT_EQ(0, helper_delegate_->num_calls_update_xrandr_config());
165 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
168 TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationAfterSecondEvent) {
169 DispatchOutputChangeEvent(1, 10, 20, true);
171 // Simulate addition of the first output to the cached output list.
172 ScopedVector<DisplaySnapshot> outputs;
173 outputs.push_back(CreateOutput(1, 10));
174 helper_delegate_->set_cached_outputs(outputs.get());
176 DispatchOutputChangeEvent(2, 11, 20, true);
177 EXPECT_EQ(2, helper_delegate_->num_calls_notify_observers());
180 TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnDisconnect) {
181 ScopedVector<DisplaySnapshot> outputs;
182 outputs.push_back(CreateOutput(1, 10));
183 helper_delegate_->set_cached_outputs(outputs.get());
185 DispatchOutputChangeEvent(1, 10, 20, false);
186 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
189 TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnModeChange) {
190 ScopedVector<DisplaySnapshot> outputs;
191 outputs.push_back(CreateOutput(1, 10));
192 helper_delegate_->set_cached_outputs(outputs.get());
194 DispatchOutputChangeEvent(1, 10, 21, true);
195 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
198 TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnSecondOutput) {
199 ScopedVector<DisplaySnapshot> outputs;
200 outputs.push_back(CreateOutput(1, 10));
201 helper_delegate_->set_cached_outputs(outputs.get());
203 DispatchOutputChangeEvent(2, 11, 20, true);
204 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
207 TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnDifferentCrtc) {
208 ScopedVector<DisplaySnapshot> outputs;
209 outputs.push_back(CreateOutput(1, 10));
210 helper_delegate_->set_cached_outputs(outputs.get());
212 DispatchOutputChangeEvent(1, 11, 20, true);
213 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
216 TEST_F(NativeDisplayEventDispatcherX11Test,
217 CheckNotificationOnSecondOutputDisconnect) {
218 ScopedVector<DisplaySnapshot> outputs;
219 outputs.push_back(CreateOutput(1, 10));
220 outputs.push_back(CreateOutput(2, 11));
221 helper_delegate_->set_cached_outputs(outputs.get());
223 DispatchOutputChangeEvent(2, 11, 20, false);
224 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
227 TEST_F(NativeDisplayEventDispatcherX11Test,
228 AvoidDuplicateNotificationOnSecondOutputDisconnect) {
229 ScopedVector<DisplaySnapshot> outputs;
230 outputs.push_back(CreateOutput(1, 10));
231 outputs.push_back(CreateOutput(2, 11));
232 helper_delegate_->set_cached_outputs(outputs.get());
234 DispatchOutputChangeEvent(2, 11, 20, false);
235 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
237 // Simulate removal of second output from cached output list.
238 outputs.erase(outputs.begin() + 1);
239 helper_delegate_->set_cached_outputs(outputs.get());
241 DispatchOutputChangeEvent(2, 11, 20, false);
242 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
245 TEST_F(NativeDisplayEventDispatcherX11Test,
246 ForceUpdateAfterCacheExpiration) {
247 // +1 to compenstate a possible rounding error.
248 const int kHalfOfExpirationMs =
249 NativeDisplayEventDispatcherX11::kUseCacheAfterStartupMs / 2 + 1;
251 ScopedVector<DisplaySnapshot> outputs;
252 outputs.push_back(CreateOutput(1, 10));
253 outputs.push_back(CreateOutput(2, 11));
254 helper_delegate_->set_cached_outputs(outputs.get());
256 EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
258 // Duplicated event will be ignored during the startup.
259 DispatchOutputChangeEvent(2, 11, 20, true);
260 EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
262 test_tick_clock_->Advance(base::TimeDelta::FromMilliseconds(
263 kHalfOfExpirationMs));
265 // Duplicated event will still be ignored.
266 DispatchOutputChangeEvent(2, 11, 20, true);
267 EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
269 // The startup timeout has been elapsed. Duplicated event
270 // should not be ignored.
271 test_tick_clock_->Advance(
272 base::TimeDelta::FromMilliseconds(kHalfOfExpirationMs));
273 DispatchOutputChangeEvent(2, 11, 20, true);
274 EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
276 // Sending the same event immediately shoudldn't be ignored.
277 DispatchOutputChangeEvent(2, 11, 20, true);
278 EXPECT_EQ(2, helper_delegate_->num_calls_notify_observers());
280 // Advancing time further should not change the behavior.
281 test_tick_clock_->Advance(base::TimeDelta::FromMilliseconds(
282 kHalfOfExpirationMs));
283 DispatchOutputChangeEvent(2, 11, 20, true);
284 EXPECT_EQ(3, helper_delegate_->num_calls_notify_observers());
286 test_tick_clock_->Advance(
287 base::TimeDelta::FromMilliseconds(kHalfOfExpirationMs));
288 DispatchOutputChangeEvent(2, 11, 20, true);
289 EXPECT_EQ(4, helper_delegate_->num_calls_notify_observers());
292 } // namespace ui