| 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 |