diff options
author | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-07 00:19:07 +0000 |
---|---|---|
committer | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-07 00:19:07 +0000 |
commit | 185e3c8b02e3ee0ff8090b5d68fd2e4530952756 (patch) | |
tree | 40f68203bbcb53535f86a513e7b5e83a762fafac /ash/wm | |
parent | 277222d92e9c69a50d1a3e57798c9603ba5cad63 (diff) | |
download | chromium_src-185e3c8b02e3ee0ff8090b5d68fd2e4530952756.zip chromium_src-185e3c8b02e3ee0ff8090b5d68fd2e4530952756.tar.gz chromium_src-185e3c8b02e3ee0ff8090b5d68fd2e4530952756.tar.bz2 |
ash: Fix inconsistent fullscreen video reports.
Report video as fullscreen whenever a fullscreen window
exists, regardless of whether the video that triggered the
report was occurring in that window. This fixes a case where
simultaneously playing fullscreen and non-fullscreen videos
could result in reports bouncing back and forth between the
two states.
BUG=340666
Review URL: https://codereview.chromium.org/145813004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249552 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm')
-rw-r--r-- | ash/wm/video_detector.cc | 27 | ||||
-rw-r--r-- | ash/wm/video_detector_unittest.cc | 54 |
2 files changed, 71 insertions, 10 deletions
diff --git a/ash/wm/video_detector.cc b/ash/wm/video_detector.cc index 33eba33..d24a0d9 100644 --- a/ash/wm/video_detector.cc +++ b/ash/wm/video_detector.cc @@ -5,6 +5,7 @@ #include "ash/wm/video_detector.h" #include "ash/shell.h" +#include "ash/shell_window_ids.h" #include "ash/wm/window_state.h" #include "ui/aura/env.h" #include "ui/aura/root_window.h" @@ -122,13 +123,31 @@ void VideoDetector::MaybeNotifyObservers(aura::Window* window, if (!window->GetBoundsInRootWindow().Intersects(root_bounds)) return; - aura::Window* toplevel_window = views::corewm::GetToplevelWindow(window); - bool is_fullscreen = toplevel_window ? - wm::GetWindowState(toplevel_window)->IsFullscreen() : false; + // As a relatively-cheap way to avoid flipping back and forth between + // fullscreen and non-fullscreen notifications when one video is playing in a + // fullscreen window and a second video is playing in a non-fullscreen window, + // report fullscreen video whenever a fullscreen window exists on any desktop + // regardless of whether the video is actually playing in that window: + // http://crbug.com/340666 + bool fullscreen_window_exists = false; + std::vector<aura::Window*> containers = + Shell::GetContainersFromAllRootWindows( + internal::kShellWindowId_DefaultContainer, NULL); + for (std::vector<aura::Window*>::const_iterator container = + containers.begin(); container != containers.end(); ++container) { + const aura::Window::Windows& windows = (*container)->children(); + for (aura::Window::Windows::const_iterator window = windows.begin(); + window != windows.end(); ++window) { + if (wm::GetWindowState(*window)->IsFullscreen()) { + fullscreen_window_exists = true; + break; + } + } + } FOR_EACH_OBSERVER(VideoDetectorObserver, observers_, - OnVideoDetected(is_fullscreen)); + OnVideoDetected(fullscreen_window_exists)); last_observer_notification_time_ = now; } diff --git a/ash/wm/video_detector_unittest.cc b/ash/wm/video_detector_unittest.cc index 7c37d08..287223d 100644 --- a/ash/wm/video_detector_unittest.cc +++ b/ash/wm/video_detector_unittest.cc @@ -6,7 +6,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" -#include "ash/wm/window_util.h" +#include "ash/wm/window_state.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/time/time.h" @@ -275,20 +275,62 @@ TEST_F(VideoDetectorTest, RepeatedNotifications) { // Test that the observer receives a true value when the window is fullscreen. TEST_F(VideoDetectorTest, FullscreenWindow) { - gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768)); + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("1024x768,1024x768"); + + const gfx::Rect kLeftBounds(gfx::Point(), gfx::Size(1024, 768)); scoped_ptr<aura::Window> window( - CreateTestWindowInShell(SK_ColorRED, 12345, window_bounds)); - window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); + CreateTestWindowInShell(SK_ColorRED, 12345, kLeftBounds)); + wm::WindowState window_state(window.get()); + window_state.ToggleFullscreen(); + ASSERT_TRUE(window_state.IsFullscreen()); window->Focus(); - gfx::Rect update_region( + const gfx::Rect kUpdateRegion( gfx::Point(), gfx::Size(VideoDetector::kMinUpdateWidth, VideoDetector::kMinUpdateHeight)); for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) - detector_->OnWindowPaintScheduled(window.get(), update_region); + detector_->OnWindowPaintScheduled(window.get(), kUpdateRegion); + EXPECT_EQ(1, observer_->num_invocations()); + EXPECT_EQ(1, observer_->num_fullscreens()); + EXPECT_EQ(0, observer_->num_not_fullscreens()); + + // Make the first window non-fullscreen and open a second fullscreen window on + // a different desktop. + window_state.ToggleFullscreen(); + ASSERT_FALSE(window_state.IsFullscreen()); + const gfx::Rect kRightBounds(gfx::Point(1024, 0), gfx::Size(1024, 768)); + scoped_ptr<aura::Window> other_window( + CreateTestWindowInShell(SK_ColorBLUE, 6789, kRightBounds)); + wm::WindowState other_window_state(other_window.get()); + other_window_state.ToggleFullscreen(); + ASSERT_TRUE(other_window_state.IsFullscreen()); + + // When video is detected in the first (now non-fullscreen) window, fullscreen + // video should still be reported due to the second window being fullscreen. + // This avoids situations where non-fullscreen video could be reported when + // multiple videos are playing in fullscreen and non-fullscreen windows. + observer_->reset_stats(); + AdvanceTime(base::TimeDelta::FromSeconds(2)); + for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) + detector_->OnWindowPaintScheduled(window.get(), kUpdateRegion); EXPECT_EQ(1, observer_->num_invocations()); EXPECT_EQ(1, observer_->num_fullscreens()); EXPECT_EQ(0, observer_->num_not_fullscreens()); + + // Make the second window non-fullscreen and check that the next video report + // is non-fullscreen. + other_window_state.ToggleFullscreen(); + ASSERT_FALSE(other_window_state.IsFullscreen()); + observer_->reset_stats(); + AdvanceTime(base::TimeDelta::FromSeconds(2)); + for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i) + detector_->OnWindowPaintScheduled(window.get(), kUpdateRegion); + EXPECT_EQ(1, observer_->num_invocations()); + EXPECT_EQ(0, observer_->num_fullscreens()); + EXPECT_EQ(1, observer_->num_not_fullscreens()); } } // namespace test |