1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <X11/extensions/Xrandr.h>
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#undef Bool
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#undef None
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/test/simple_test_tick_clock.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/display/chromeos/x11/display_mode_x11.h"
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/display/chromeos/x11/display_snapshot_x11.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/display/chromeos/x11/native_display_delegate_x11.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/display/chromeos/x11/native_display_event_dispatcher_x11.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ui {
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)DisplaySnapshotX11* CreateOutput(RROutput output, RRCrtc crtc) {
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  static const DisplayModeX11* kDefaultDisplayMode =
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new DisplayModeX11(gfx::Size(1, 1), false, 60.0f, 20);
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DisplaySnapshotX11* snapshot = new DisplaySnapshotX11(
2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      0,
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      false,
2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      gfx::Point(0, 0),
2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      gfx::Size(0, 0),
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      DISPLAY_CONNECTION_TYPE_UNKNOWN,
3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      false,
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      false,
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      std::string(),
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      std::vector<const DisplayMode*>(1, kDefaultDisplayMode),
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      kDefaultDisplayMode,
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      NULL,
3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      output,
3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      crtc,
3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      0);
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return snapshot;
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class TestHelperDelegate : public NativeDisplayDelegateX11::HelperDelegate {
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestHelperDelegate();
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~TestHelperDelegate();
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int num_calls_update_xrandr_config() const {
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return num_calls_update_xrandr_config_;
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int num_calls_notify_observers() const { return num_calls_notify_observers_; }
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void set_cached_outputs(const std::vector<DisplaySnapshot*>& outputs) {
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    cached_outputs_ = outputs;
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // NativeDisplayDelegateX11::HelperDelegate overrides:
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void UpdateXRandRConfiguration(const base::NativeEvent& event)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      OVERRIDE;
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual const std::vector<DisplaySnapshot*>& GetCachedDisplays() const
6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      OVERRIDE;
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void NotifyDisplayObservers() OVERRIDE;
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int num_calls_update_xrandr_config_;
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int num_calls_notify_observers_;
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::vector<DisplaySnapshot*> cached_outputs_;
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestHelperDelegate);
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TestHelperDelegate::TestHelperDelegate()
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : num_calls_update_xrandr_config_(0), num_calls_notify_observers_(0) {}
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TestHelperDelegate::~TestHelperDelegate() {}
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestHelperDelegate::UpdateXRandRConfiguration(
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::NativeEvent& event) {
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ++num_calls_update_xrandr_config_;
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst std::vector<DisplaySnapshot*>& TestHelperDelegate::GetCachedDisplays()
8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const {
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return cached_outputs_;
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestHelperDelegate::NotifyDisplayObservers() {
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ++num_calls_notify_observers_;
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// NativeDisplayEventDispatcherX11Test
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class NativeDisplayEventDispatcherX11Test : public testing::Test {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NativeDisplayEventDispatcherX11Test();
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~NativeDisplayEventDispatcherX11Test();
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected:
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DispatchScreenChangeEvent();
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DispatchOutputChangeEvent(RROutput output,
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 RRCrtc crtc,
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 RRMode mode,
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 bool connected);
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int xrandr_event_base_;
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<TestHelperDelegate> helper_delegate_;
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<NativeDisplayEventDispatcherX11> dispatcher_;
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::SimpleTestTickClock* test_tick_clock_;  // Owned by |dispatcher_|.
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NativeDisplayEventDispatcherX11Test);
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NativeDisplayEventDispatcherX11Test::NativeDisplayEventDispatcherX11Test()
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : xrandr_event_base_(10),
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      helper_delegate_(new TestHelperDelegate()),
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dispatcher_(new NativeDisplayEventDispatcherX11(helper_delegate_.get(),
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                      xrandr_event_base_)),
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      test_tick_clock_(new base::SimpleTestTickClock) {
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  test_tick_clock_->Advance(base::TimeDelta::FromMilliseconds(1));
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  dispatcher_->SetTickClockForTest(
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      scoped_ptr<base::TickClock>(test_tick_clock_));
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NativeDisplayEventDispatcherX11Test::~NativeDisplayEventDispatcherX11Test() {}
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NativeDisplayEventDispatcherX11Test::DispatchScreenChangeEvent() {
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  XRRScreenChangeNotifyEvent event = {0};
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event.type = xrandr_event_base_ + RRScreenChangeNotify;
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  dispatcher_->DispatchEvent(reinterpret_cast<const PlatformEvent>(&event));
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NativeDisplayEventDispatcherX11Test::DispatchOutputChangeEvent(
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RROutput output,
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RRCrtc crtc,
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RRMode mode,
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool connected) {
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  XRROutputChangeNotifyEvent event = {0};
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event.type = xrandr_event_base_ + RRNotify;
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event.subtype = RRNotify_OutputChange;
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event.output = output;
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event.crtc = crtc;
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event.mode = mode;
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event.connection = connected ? RR_Connected : RR_Disconnected;
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  dispatcher_->DispatchEvent(reinterpret_cast<const PlatformEvent>(&event));
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test, OnScreenChangedEvent) {
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchScreenChangeEvent();
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_update_xrandr_config());
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnFirstEvent) {
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(1, 10, 20, true);
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, helper_delegate_->num_calls_update_xrandr_config());
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationAfterSecondEvent) {
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(1, 10, 20, true);
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Simulate addition of the first output to the cached output list.
17223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ScopedVector<DisplaySnapshot> outputs;
17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(1, 10));
17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(2, 11, 20, true);
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, helper_delegate_->num_calls_notify_observers());
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnDisconnect) {
18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ScopedVector<DisplaySnapshot> outputs;
18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(1, 10));
18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(1, 10, 20, false);
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnModeChange) {
19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ScopedVector<DisplaySnapshot> outputs;
19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(1, 10));
19223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(1, 10, 21, true);
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnSecondOutput) {
19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ScopedVector<DisplaySnapshot> outputs;
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(1, 10));
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(2, 11, 20, true);
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test, CheckNotificationOnDifferentCrtc) {
20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ScopedVector<DisplaySnapshot> outputs;
20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(1, 10));
21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(1, 11, 20, true);
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test,
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       CheckNotificationOnSecondOutputDisconnect) {
21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ScopedVector<DisplaySnapshot> outputs;
21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(1, 10));
22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(2, 11));
22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(2, 11, 20, false);
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeDisplayEventDispatcherX11Test,
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       AvoidDuplicateNotificationOnSecondOutputDisconnect) {
22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ScopedVector<DisplaySnapshot> outputs;
23023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(1, 10));
23123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  outputs.push_back(CreateOutput(2, 11));
23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(2, 11, 20, false);
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Simulate removal of second output from cached output list.
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  outputs.erase(outputs.begin() + 1);
23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  helper_delegate_->set_cached_outputs(outputs.get());
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchOutputChangeEvent(2, 11, 20, false);
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
245effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(NativeDisplayEventDispatcherX11Test,
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       ForceUpdateAfterCacheExpiration) {
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // +1 to compenstate a possible rounding error.
248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const int kHalfOfExpirationMs =
249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      NativeDisplayEventDispatcherX11::kUseCacheAfterStartupMs / 2 + 1;
250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ScopedVector<DisplaySnapshot> outputs;
252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  outputs.push_back(CreateOutput(1, 10));
253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  outputs.push_back(CreateOutput(2, 11));
254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  helper_delegate_->set_cached_outputs(outputs.get());
255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
256effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
257effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Duplicated event will be ignored during the startup.
259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DispatchOutputChangeEvent(2, 11, 20, true);
260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
262effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  test_tick_clock_->Advance(base::TimeDelta::FromMilliseconds(
263effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      kHalfOfExpirationMs));
264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Duplicated event will still be ignored.
266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DispatchOutputChangeEvent(2, 11, 20, true);
267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(0, helper_delegate_->num_calls_notify_observers());
268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // The startup timeout has been elapsed. Duplicated event
270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // should not be ignored.
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  test_tick_clock_->Advance(
272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::TimeDelta::FromMilliseconds(kHalfOfExpirationMs));
273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DispatchOutputChangeEvent(2, 11, 20, true);
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(1, helper_delegate_->num_calls_notify_observers());
275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Sending the same event immediately shoudldn't be ignored.
277effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DispatchOutputChangeEvent(2, 11, 20, true);
278effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(2, helper_delegate_->num_calls_notify_observers());
279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Advancing time further should not change the behavior.
281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  test_tick_clock_->Advance(base::TimeDelta::FromMilliseconds(
282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      kHalfOfExpirationMs));
283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DispatchOutputChangeEvent(2, 11, 20, true);
284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(3, helper_delegate_->num_calls_notify_observers());
285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  test_tick_clock_->Advance(
287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::TimeDelta::FromMilliseconds(kHalfOfExpirationMs));
288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DispatchOutputChangeEvent(2, 11, 20, true);
289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(4, helper_delegate_->num_calls_notify_observers());
290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace ui
293