summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-03 00:10:54 +0000
committerderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-03 00:10:54 +0000
commit88c9f95b1fde5a97ae8ffe96028be8a9e161985d (patch)
tree277074573350db6c26b8535135b25f8971f7359e /ash
parenta885fb3eb3923eb83e0f635211a98ba4bde5ec89 (diff)
downloadchromium_src-88c9f95b1fde5a97ae8ffe96028be8a9e161985d.zip
chromium_src-88c9f95b1fde5a97ae8ffe96028be8a9e161985d.tar.gz
chromium_src-88c9f95b1fde5a97ae8ffe96028be8a9e161985d.tar.bz2
ash: Make frequency of video activity reports more reliable.
This makes ash::VideoDetector maintain a circular buffer containing timestamps of recent updates to each window instead of maintaining a counter and resetting it once a second. The old approach resulted in occasional longer delays between reports of video activity, which could lead the Chrome OS power manager to erroneously believe that the activity had stopped. BUG=265311 Review URL: https://chromiumcodereview.appspot.com/21128004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215414 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/wm/video_detector.cc34
-rw-r--r--ash/wm/video_detector_unittest.cc33
2 files changed, 48 insertions, 19 deletions
diff --git a/ash/wm/video_detector.cc b/ash/wm/video_detector.cc
index 7116bae..743b49c 100644
--- a/ash/wm/video_detector.cc
+++ b/ash/wm/video_detector.cc
@@ -22,32 +22,38 @@ const double VideoDetector::kNotifyIntervalSec = 1.0;
// likely that a video is playing in it.
class VideoDetector::WindowInfo {
public:
- WindowInfo() : num_video_updates_in_second_(0) {}
+ WindowInfo() : buffer_start_(0), buffer_size_(0) {}
- // Handles an update within a window, returning true if this update made us
- // believe that a video is playing in the window. true is returned at most
- // once per second.
+ // Handles an update within a window, returning true if it appears that
+ // video is currently playing in the window.
bool RecordUpdateAndCheckForVideo(const gfx::Rect& region,
base::TimeTicks now) {
if (region.width() < kMinUpdateWidth || region.height() < kMinUpdateHeight)
return false;
- if (second_start_time_.is_null() ||
- (now - second_start_time_).InSecondsF() >= 1.0) {
- second_start_time_ = now;
- num_video_updates_in_second_ = 0;
+ // If the buffer is full, drop the first timestamp.
+ if (buffer_size_ == static_cast<size_t>(kMinFramesPerSecond)) {
+ buffer_start_ = (buffer_start_ + 1) % kMinFramesPerSecond;
+ buffer_size_--;
}
- num_video_updates_in_second_++;
- return num_video_updates_in_second_ == kMinFramesPerSecond;
+ update_times_[(buffer_start_ + buffer_size_) % kMinFramesPerSecond] = now;
+ buffer_size_++;
+
+ return buffer_size_ == static_cast<size_t>(kMinFramesPerSecond) &&
+ (now - update_times_[buffer_start_]).InSecondsF() <= 1.0;
}
private:
- // Number of video-sized updates that we've seen in the second starting at
- // |second_start_time_|. (Keeping a rolling window is overkill here.)
- int num_video_updates_in_second_;
+ // Circular buffer containing update times of the last (up to
+ // |kMinFramesPerSecond|) video-sized updates to this window.
+ base::TimeTicks update_times_[kMinFramesPerSecond];
+
+ // Index into |update_times_| of the oldest update.
+ size_t buffer_start_;
- base::TimeTicks second_start_time_;
+ // Number of updates stored in |update_times_|.
+ size_t buffer_size_;
DISALLOW_COPY_AND_ASSIGN(WindowInfo);
};
diff --git a/ash/wm/video_detector_unittest.cc b/ash/wm/video_detector_unittest.cc
index 96e0787..01c79cf 100644
--- a/ash/wm/video_detector_unittest.cc
+++ b/ash/wm/video_detector_unittest.cc
@@ -132,15 +132,38 @@ TEST_F(VideoDetectorTest, Basic) {
EXPECT_EQ(0, observer_->num_fullscreens());
EXPECT_EQ(1, observer_->num_not_fullscreens());
- // Spread out the frames over two seconds; we shouldn't detect video.
+ // Spread out the frames over a longer period of time, but send enough
+ // over a one-second window that the observer should be notified.
observer_->reset_stats();
AdvanceTime(base::TimeDelta::FromSeconds(2));
- for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i)
+ detector_->OnWindowPaintScheduled(window.get(), update_region);
+ EXPECT_EQ(0, observer_->num_invocations());
+
+ AdvanceTime(base::TimeDelta::FromMilliseconds(500));
+ const int kNumFrames = VideoDetector::kMinFramesPerSecond + 1;
+ base::TimeDelta kInterval =
+ base::TimeDelta::FromMilliseconds(1000 / kNumFrames);
+ for (int i = 0; i < kNumFrames; ++i) {
+ AdvanceTime(kInterval);
detector_->OnWindowPaintScheduled(window.get(), update_region);
- AdvanceTime(base::TimeDelta::FromSeconds(1));
- for (int i = 0; i < VideoDetector::kMinFramesPerSecond - 1; ++i)
+ }
+ EXPECT_EQ(1, observer_->num_invocations());
+
+ // Keep going and check that the observer is notified again.
+ for (int i = 0; i < kNumFrames; ++i) {
+ AdvanceTime(kInterval);
detector_->OnWindowPaintScheduled(window.get(), update_region);
- EXPECT_EQ(0, observer_->num_invocations());
+ }
+ EXPECT_EQ(2, observer_->num_invocations());
+
+ // Send updates at a slower rate and check that the observer isn't notified.
+ base::TimeDelta kSlowInterval = base::TimeDelta::FromMilliseconds(
+ 1000 / (VideoDetector::kMinFramesPerSecond - 2));
+ for (int i = 0; i < kNumFrames; ++i) {
+ AdvanceTime(kSlowInterval);
+ detector_->OnWindowPaintScheduled(window.get(), update_region);
+ }
+ EXPECT_EQ(2, observer_->num_invocations());
}
TEST_F(VideoDetectorTest, Shutdown) {