OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/video_detector.h" | 5 #include "ash/wm/video_detector.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/test/ash_test_base.h" | 8 #include "ash/test/ash_test_base.h" |
| 9 #include "ash/wm/mock_video_detector_observer.h" |
9 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
11 #include "base/time.h" | 12 #include "base/time.h" |
12 #include "third_party/skia/include/core/SkColor.h" | 13 #include "third_party/skia/include/core/SkColor.h" |
13 #include "ui/aura/client/window_types.h" | 14 #include "ui/aura/client/window_types.h" |
14 #include "ui/aura/root_window.h" | 15 #include "ui/aura/root_window.h" |
15 #include "ui/aura/test/test_windows.h" | 16 #include "ui/aura/test/test_windows.h" |
16 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
17 #include "ui/gfx/rect.h" | 18 #include "ui/gfx/rect.h" |
18 | 19 |
| 20 using ::testing::StrictMock; |
| 21 |
19 namespace ash { | 22 namespace ash { |
20 namespace test { | 23 namespace test { |
21 | 24 |
22 // Implementation that just counts the number of times we've been told that a | |
23 // video is playing. | |
24 class TestVideoDetectorObserver : public VideoDetectorObserver { | |
25 public: | |
26 TestVideoDetectorObserver() : num_invocations_(0) {} | |
27 | |
28 int num_invocations() const { return num_invocations_; } | |
29 void reset_stats() { num_invocations_ = 0; } | |
30 | |
31 // VideoDetectorObserver implementation. | |
32 virtual void OnVideoDetected() OVERRIDE { num_invocations_++; } | |
33 | |
34 private: | |
35 // Number of times that OnVideoDetected() has been called. | |
36 int num_invocations_; | |
37 | |
38 DISALLOW_COPY_AND_ASSIGN(TestVideoDetectorObserver); | |
39 }; | |
40 | |
41 class VideoDetectorTest : public AshTestBase { | 25 class VideoDetectorTest : public AshTestBase { |
42 public: | 26 public: |
43 VideoDetectorTest() {} | 27 VideoDetectorTest() {} |
44 virtual ~VideoDetectorTest() {} | 28 virtual ~VideoDetectorTest() {} |
45 | 29 |
46 virtual void SetUp() OVERRIDE { | 30 virtual void SetUp() OVERRIDE { |
47 AshTestBase::SetUp(); | 31 AshTestBase::SetUp(); |
48 observer_.reset(new TestVideoDetectorObserver); | |
49 detector_ = Shell::GetInstance()->video_detector(); | 32 detector_ = Shell::GetInstance()->video_detector(); |
50 detector_->AddObserver(observer_.get()); | 33 detector_->AddObserver(observer_.get()); |
51 | 34 |
52 now_ = base::TimeTicks::Now(); | 35 now_ = base::TimeTicks::Now(); |
53 detector_->set_now_for_test(now_); | 36 detector_->set_now_for_test(now_); |
54 } | 37 } |
55 | 38 |
56 virtual void TearDown() OVERRIDE { | 39 virtual void TearDown() OVERRIDE { |
57 detector_->RemoveObserver(observer_.get()); | 40 detector_->RemoveObserver(observer_.get()); |
58 AshTestBase::TearDown(); | 41 AshTestBase::TearDown(); |
59 } | 42 } |
60 | 43 |
61 protected: | 44 protected: |
62 // Move |detector_|'s idea of the current time forward by |delta|. | 45 // Move |detector_|'s idea of the current time forward by |delta|. |
63 void AdvanceTime(base::TimeDelta delta) { | 46 void AdvanceTime(base::TimeDelta delta) { |
64 now_ += delta; | 47 now_ += delta; |
65 detector_->set_now_for_test(now_); | 48 detector_->set_now_for_test(now_); |
66 } | 49 } |
67 | 50 |
68 VideoDetector* detector_; // not owned | 51 VideoDetector* detector_; // not owned |
69 | 52 |
70 scoped_ptr<TestVideoDetectorObserver> observer_; | 53 StrictMock<MockVideoDetectorObserver> observer_; |
71 | 54 |
72 base::TimeTicks now_; | 55 base::TimeTicks now_; |
73 | 56 |
74 private: | 57 private: |
75 DISALLOW_COPY_AND_ASSIGN(VideoDetectorTest); | 58 DISALLOW_COPY_AND_ASSIGN(VideoDetectorTest); |
76 }; | 59 }; |
77 | 60 |
78 TEST_F(VideoDetectorTest, Basic) { | 61 TEST_F(VideoDetectorTest, Basic) { |
79 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); | 62 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); |
80 scoped_ptr<aura::Window> window( | 63 scoped_ptr<aura::Window> window( |
81 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); | 64 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); |
82 | 65 |
83 // Send enough updates, but make them be too small to trigger detection. | 66 // Send enough updates, but make them be too small to trigger detection. |
84 gfx::Rect update_region( | 67 gfx::Rect update_region( |
85 gfx::Point(), | 68 gfx::Point(), |
86 gfx::Size(VideoDetector::kMinUpdateWidth - 1, | 69 gfx::Size(VideoDetector::kMinUpdateWidth - 1, |
87 VideoDetector::kMinUpdateHeight)); | 70 VideoDetector::kMinUpdateHeight)); |
88 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 71 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
89 detector_->OnWindowPaintScheduled(window.get(), update_region); | 72 detector_->OnWindowPaintScheduled(window.get(), update_region); |
90 EXPECT_EQ(0, observer_->num_invocations()); | 73 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer_)); |
91 | 74 |
92 // Send not-quite-enough adaquately-sized updates. | 75 // Send not-quite-enough adaquately-sized updates. |
93 observer_->reset_stats(); | |
94 AdvanceTime(base::TimeDelta::FromSeconds(2)); | 76 AdvanceTime(base::TimeDelta::FromSeconds(2)); |
95 update_region.set_size( | 77 update_region.set_size( |
96 gfx::Size(VideoDetector::kMinUpdateWidth, | 78 gfx::Size(VideoDetector::kMinUpdateWidth, |
97 VideoDetector::kMinUpdateHeight)); | 79 VideoDetector::kMinUpdateHeight)); |
98 for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i) | 80 for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i) |
99 detector_->OnWindowPaintScheduled(window.get(), update_region); | 81 detector_->OnWindowPaintScheduled(window.get(), update_region); |
100 EXPECT_EQ(0, observer_->num_invocations()); | 82 Mock::VerifyAndClearExpectations(&observer_); |
101 | 83 |
102 // We should get notified after the next update, but not in response to | 84 // We should get notified after the next update, but not in response to |
103 // additional updates. | 85 // additional updates. |
| 86 observer_.ExpectOnVideoDetected(false); |
104 detector_->OnWindowPaintScheduled(window.get(), update_region); | 87 detector_->OnWindowPaintScheduled(window.get(), update_region); |
105 EXPECT_EQ(1, observer_->num_invocations()); | 88 Mock::VerifyAndClearExpectations(&observer_); |
| 89 observer_.ExpectOnVideoDetected(false); |
106 detector_->OnWindowPaintScheduled(window.get(), update_region); | 90 detector_->OnWindowPaintScheduled(window.get(), update_region); |
107 EXPECT_EQ(1, observer_->num_invocations()); | 91 Mock::VerifyAndClearExpectations(&observer_); |
108 | 92 |
109 // Spread out the frames over two seconds; we shouldn't detect video. | 93 // Spread out the frames over two seconds; we shouldn't detect video. |
110 observer_->reset_stats(); | |
111 AdvanceTime(base::TimeDelta::FromSeconds(2)); | 94 AdvanceTime(base::TimeDelta::FromSeconds(2)); |
112 for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i) | 95 for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i) |
113 detector_->OnWindowPaintScheduled(window.get(), update_region); | 96 detector_->OnWindowPaintScheduled(window.get(), update_region); |
114 AdvanceTime(base::TimeDelta::FromSeconds(1)); | 97 AdvanceTime(base::TimeDelta::FromSeconds(1)); |
115 for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i) | 98 for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i) |
116 detector_->OnWindowPaintScheduled(window.get(), update_region); | 99 detector_->OnWindowPaintScheduled(window.get(), update_region); |
117 EXPECT_EQ(0, observer_->num_invocations()); | |
118 } | 100 } |
119 | 101 |
120 TEST_F(VideoDetectorTest, WindowNotVisible) { | 102 TEST_F(VideoDetectorTest, WindowNotVisible) { |
121 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); | 103 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); |
122 scoped_ptr<aura::Window> window( | 104 scoped_ptr<aura::Window> window( |
123 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); | 105 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); |
124 | 106 |
125 // Reparent the window to the root to make sure that visibility changes aren't | 107 // Reparent the window to the root to make sure that visibility changes aren't |
126 // animated. | 108 // animated. |
127 Shell::GetPrimaryRootWindow()->AddChild(window.get()); | 109 Shell::GetPrimaryRootWindow()->AddChild(window.get()); |
128 | 110 |
129 // We shouldn't report video that's played in a hidden window. | 111 // We shouldn't report video that's played in a hidden window. |
130 window->Hide(); | 112 window->Hide(); |
131 gfx::Rect update_region( | 113 gfx::Rect update_region( |
132 gfx::Point(), | 114 gfx::Point(), |
133 gfx::Size(VideoDetector::kMinUpdateWidth, | 115 gfx::Size(VideoDetector::kMinUpdateWidth, |
134 VideoDetector::kMinUpdateHeight)); | 116 VideoDetector::kMinUpdateHeight)); |
135 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 117 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
136 detector_->OnWindowPaintScheduled(window.get(), update_region); | 118 detector_->OnWindowPaintScheduled(window.get(), update_region); |
137 EXPECT_EQ(0, observer_->num_invocations()); | 119 Mock::VerifyAndClearExpectations(&observer_); |
138 | 120 |
139 // Make the window visible and send more updates. | 121 // Make the window visible and send more updates. |
140 observer_->reset_stats(); | |
141 AdvanceTime(base::TimeDelta::FromSeconds(2)); | 122 AdvanceTime(base::TimeDelta::FromSeconds(2)); |
142 window->Show(); | 123 window->Show(); |
| 124 observer_.ExpectOnVideoDetected(false); |
143 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 125 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
144 detector_->OnWindowPaintScheduled(window.get(), update_region); | 126 detector_->OnWindowPaintScheduled(window.get(), update_region); |
145 EXPECT_EQ(1, observer_->num_invocations()); | 127 Mock::VerifyAndClearExpectations(&observer_); |
146 | 128 |
147 // We also shouldn't report video in a window that's fully offscreen. | 129 // We also shouldn't report video in a window that's fully offscreen. |
148 observer_->reset_stats(); | |
149 AdvanceTime(base::TimeDelta::FromSeconds(2)); | 130 AdvanceTime(base::TimeDelta::FromSeconds(2)); |
150 gfx::Rect offscreen_bounds( | 131 gfx::Rect offscreen_bounds( |
151 gfx::Point(Shell::GetPrimaryRootWindow()->bounds().width(), 0), | 132 gfx::Point(Shell::GetPrimaryRootWindow()->bounds().width(), 0), |
152 window_bounds.size()); | 133 window_bounds.size()); |
153 window->SetBounds(offscreen_bounds); | 134 window->SetBounds(offscreen_bounds); |
154 ASSERT_EQ(offscreen_bounds, window->bounds()); | 135 ASSERT_EQ(offscreen_bounds, window->bounds()); |
155 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 136 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
156 detector_->OnWindowPaintScheduled(window.get(), update_region); | 137 detector_->OnWindowPaintScheduled(window.get(), update_region); |
157 EXPECT_EQ(0, observer_->num_invocations()); | |
158 } | 138 } |
159 | 139 |
160 TEST_F(VideoDetectorTest, MultipleWindows) { | 140 TEST_F(VideoDetectorTest, MultipleWindows) { |
161 // Create two windows. | 141 // Create two windows. |
162 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); | 142 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); |
163 scoped_ptr<aura::Window> window1( | 143 scoped_ptr<aura::Window> window1( |
164 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); | 144 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); |
165 scoped_ptr<aura::Window> window2( | 145 scoped_ptr<aura::Window> window2( |
166 aura::test::CreateTestWindow(SK_ColorBLUE, 23456, window_bounds, NULL)); | 146 aura::test::CreateTestWindow(SK_ColorBLUE, 23456, window_bounds, NULL)); |
167 | 147 |
168 // Even if there's video playing in both, the observer should only receive a | 148 // Even if there's video playing in both, the observer should only receive a |
169 // single notification. | 149 // single notification. |
170 gfx::Rect update_region( | 150 gfx::Rect update_region( |
171 gfx::Point(), | 151 gfx::Point(), |
172 gfx::Size(VideoDetector::kMinUpdateWidth, | 152 gfx::Size(VideoDetector::kMinUpdateWidth, |
173 VideoDetector::kMinUpdateHeight)); | 153 VideoDetector::kMinUpdateHeight)); |
| 154 observer_.ExpectOnVideoDetected(false); |
174 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 155 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
175 detector_->OnWindowPaintScheduled(window1.get(), update_region); | 156 detector_->OnWindowPaintScheduled(window1.get(), update_region); |
176 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 157 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
177 detector_->OnWindowPaintScheduled(window2.get(), update_region); | 158 detector_->OnWindowPaintScheduled(window2.get(), update_region); |
178 EXPECT_EQ(1, observer_->num_invocations()); | |
179 } | 159 } |
180 | 160 |
181 // Test that the observer receives repeated notifications. | 161 // Test that the observer receives repeated notifications. |
182 TEST_F(VideoDetectorTest, RepeatedNotifications) { | 162 TEST_F(VideoDetectorTest, RepeatedNotifications) { |
183 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); | 163 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); |
184 scoped_ptr<aura::Window> window( | 164 scoped_ptr<aura::Window> window( |
185 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); | 165 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); |
186 | 166 |
187 gfx::Rect update_region( | 167 gfx::Rect update_region( |
188 gfx::Point(), | 168 gfx::Point(), |
189 gfx::Size(VideoDetector::kMinUpdateWidth, | 169 gfx::Size(VideoDetector::kMinUpdateWidth, |
190 VideoDetector::kMinUpdateHeight)); | 170 VideoDetector::kMinUpdateHeight)); |
| 171 observer_.ExpectOnVideoDetected(false); |
191 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 172 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
192 detector_->OnWindowPaintScheduled(window.get(), update_region); | 173 detector_->OnWindowPaintScheduled(window.get(), update_region); |
193 EXPECT_EQ(1, observer_->num_invocations()); | 174 Mock::VerifyAndClearExpectations(&observer_); |
194 | 175 |
195 // Let enough time pass that a second notification should be sent. | 176 // Let enough time pass that a second notification should be sent. |
196 observer_->reset_stats(); | 177 observer_.ExpectOnVideoDetected(false); |
197 AdvanceTime(base::TimeDelta::FromSeconds( | 178 AdvanceTime(base::TimeDelta::FromSeconds( |
198 static_cast<int64>(VideoDetector::kNotifyIntervalSec + 1))); | 179 static_cast<int64>(VideoDetector::kNotifyIntervalSec + 1))); |
199 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) | 180 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
200 detector_->OnWindowPaintScheduled(window.get(), update_region); | 181 detector_->OnWindowPaintScheduled(window.get(), update_region); |
201 EXPECT_EQ(1, observer_->num_invocations()); | 182 } |
| 183 |
| 184 // Test that the observer receives a true value when the window is fullscreen. |
| 185 TEST_F(VideoDetectorTest, FullscreenWindow) { |
| 186 gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); |
| 187 scoped_ptr<aura::Window> window( |
| 188 aura::test::CreateTestWindow(SK_ColorRED, 12345, window_bounds, NULL)); |
| 189 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); |
| 190 |
| 191 gfx::Rect update_region( |
| 192 gfx::Point(), |
| 193 gfx::Size(VideoDetector::kMinUpdateWidth, |
| 194 VideoDetector::kMinUpdateHeight)); |
| 195 observer_.ExpectOnVideoDetected(true); |
| 196 for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) |
| 197 detector_->OnWindowPaintScheduled(window.get(), update_region); |
202 } | 198 } |
203 | 199 |
204 } // namespace test | 200 } // namespace test |
205 } // namespace ash | 201 } // namespace ash |
OLD | NEW |