Index: media/blink/watch_time_reporter_unittest.cc |
diff --git a/media/blink/watch_time_reporter_unittest.cc b/media/blink/watch_time_reporter_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6ab2957f726c1ff9960e7912af0817e091cc323a |
--- /dev/null |
+++ b/media/blink/watch_time_reporter_unittest.cc |
@@ -0,0 +1,548 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <memory> |
+ |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/run_loop.h" |
+#include "base/test/test_message_loop.h" |
+#include "media/base/mock_media_log.h" |
+#include "media/blink/watch_time_reporter.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace media { |
+ |
+constexpr gfx::Size kSizeJustRight = gfx::Size(201, 201); |
+ |
+#define EXPECT_WATCH_TIME(key, value) \ |
+ EXPECT_CALL(*media_log_, OnWatchTimeUpdate(key, value)).RetiresOnSaturation(); |
+ |
+#define EXPECT_WATCH_TIME_FINALIZED() \ |
+ EXPECT_CALL(*media_log_, OnWatchTimeFinalized()).RetiresOnSaturation(); |
+ |
+#define EXPECT_POWER_WATCH_TIME_FINALIZED() \ |
+ EXPECT_CALL(*media_log_, OnPowerWatchTimeFinalized()).RetiresOnSaturation(); |
+ |
+class WatchTimeReporterTest : public testing::Test { |
+ public: |
+ WatchTimeReporterTest() |
+ : media_log_(new testing::StrictMock<WatchTimeLogMonitor>()) {} |
+ ~WatchTimeReporterTest() override {} |
+ |
+ protected: |
+ class WatchTimeLogMonitor : public MediaLog { |
+ public: |
+ WatchTimeLogMonitor() {} |
+ |
+ void AddEvent(std::unique_ptr<MediaLogEvent> event) override { |
+ ASSERT_EQ(event->type, MediaLogEvent::Type::WATCH_TIME_UPDATE); |
+ |
+ for (base::DictionaryValue::Iterator it(event->params); !it.IsAtEnd(); |
+ it.Advance()) { |
+ bool finalize; |
+ if (it.value().GetAsBoolean(&finalize)) { |
+ if (it.key() == MediaLog::kWatchTimeFinalize) |
+ OnWatchTimeFinalized(); |
+ else |
+ OnPowerWatchTimeFinalized(); |
+ continue; |
+ } |
+ |
+ double in_seconds; |
+ ASSERT_TRUE(it.value().GetAsDouble(&in_seconds)); |
+ OnWatchTimeUpdate(it.key(), base::TimeDelta::FromSecondsD(in_seconds)); |
+ } |
+ } |
+ |
+ MOCK_METHOD0(OnWatchTimeFinalized, void(void)); |
+ MOCK_METHOD0(OnPowerWatchTimeFinalized, void(void)); |
+ MOCK_METHOD2(OnWatchTimeUpdate, void(const std::string&, base::TimeDelta)); |
+ |
+ protected: |
+ ~WatchTimeLogMonitor() override {} |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(WatchTimeLogMonitor); |
+ }; |
+ |
+ void Initialize(bool has_audio, |
+ bool has_video, |
+ bool is_mse, |
+ bool is_encrypted, |
+ const gfx::Size& initial_video_size) { |
+ wtr_.reset(new WatchTimeReporter( |
+ has_audio, has_video, is_mse, is_encrypted, media_log_, |
+ initial_video_size, |
+ base::Bind(&WatchTimeReporterTest::GetCurrentMediaTime, |
+ base::Unretained(this)))); |
+ |
+ // Setup the reporting interval to be immediate to avoid spinning real time |
+ // within the unit test. |
+ wtr_->reporting_interval_ = base::TimeDelta(); |
+ } |
+ |
+ void CycleReportingTimer() { |
+ base::RunLoop run_loop; |
+ message_loop_.task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure()); |
+ run_loop.Run(); |
+ } |
+ |
+ bool IsMonitoring() { return wtr_->reporting_timer_.IsRunning(); } |
+ |
+ // We call directly into the reporter for this instead of using an actual |
+ // PowerMonitorTestSource since that results in a posted tasks which interfere |
+ // with our ability to test the timer. |
+ void SetOnBatteryPower(bool on_battery_power) { |
+ wtr_->is_on_battery_power_ = on_battery_power; |
+ } |
+ |
+ void OnPowerStateChange(bool on_battery_power) { |
+ wtr_->OnPowerStateChange(on_battery_power); |
+ } |
+ |
+ enum { |
+ // After |test_callback_func| is executed, should watch time continue to |
+ // accumulate? |
+ kAccumulationContinuesAfterTest = 1, |
+ |
+ // |test_callback_func| for hysteresis tests enters and exits finalize mode |
+ // for watch time, not all exits require a new current time update. |
+ kFinalizeExitDoesNotRequireCurrentTime = 2, |
+ |
+ // During finalize the watch time should not continue on the starting power |
+ // metric. By default this means the AC metric will be finalized, but if |
+ // used with |kStartOnBattery| it will be the battery metric. |
+ kFinalizePowerWatchTime = 4, |
+ |
+ // During finalize the watch time should continue on the metric opposite the |
+ // starting metric (by default it's AC, it's battery if |kStartOnBattery| is |
+ // specified. |
+ kTransitionPowerWatchTime = 8, |
+ |
+ // Indicates that power watch time should be reported to the battery metric. |
+ kStartOnBattery = 16, |
+ |
+ // Indicates an extra start event may be generated during test execution. |
+ kFinalizeInterleavedStartEvent = 32, |
+ }; |
+ |
+ template <int TestFlags = 0, typename HysteresisTestCallback> |
+ void RunHysteresisTest(HysteresisTestCallback test_callback_func) { |
+ Initialize(true, true, false, false, kSizeJustRight); |
+ |
+ // Setup all current time expectations first since they need to use the |
+ // InSequence macro for ease of use, but we don't want the watch time |
+ // expectations to be in sequence (or expectations would depend on sorted |
+ // order of histogram names). |
+ constexpr base::TimeDelta kWatchTime1 = base::TimeDelta::FromSeconds(10); |
+ constexpr base::TimeDelta kWatchTime2 = base::TimeDelta::FromSeconds(12); |
+ constexpr base::TimeDelta kWatchTime3 = base::TimeDelta::FromSeconds(15); |
+ constexpr base::TimeDelta kWatchTime4 = base::TimeDelta::FromSeconds(30); |
+ { |
+ testing::InSequence s; |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime1)); |
+ |
+ // Setup conditions depending on if the test will not resume watch time |
+ // accumulation or not; i.e. the finalize criteria will not be undone |
+ // within the hysteresis time. |
+ if (TestFlags & kAccumulationContinuesAfterTest) { |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .Times(TestFlags & (kFinalizeExitDoesNotRequireCurrentTime | |
+ kFinalizePowerWatchTime) |
+ ? 1 |
+ : 2) |
+ .WillRepeatedly(testing::Return(kWatchTime2)); |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(kWatchTime3)); |
+ } else { |
+ // Current time should be requested when entering the finalize state. |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .Times(TestFlags & kFinalizeInterleavedStartEvent ? 2 : 1) |
+ .WillRepeatedly(testing::Return(kWatchTime2)); |
+ } |
+ |
+ if (TestFlags & kTransitionPowerWatchTime) { |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(kWatchTime4)); |
+ } |
+ } |
+ |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ if (TestFlags & kStartOnBattery) |
+ SetOnBatteryPower(true); |
+ else |
+ ASSERT_FALSE(wtr_->is_on_battery_power_); |
+ |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime1); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoSrc, kWatchTime1); |
+ EXPECT_WATCH_TIME(TestFlags & kStartOnBattery |
+ ? MediaLog::kWatchTimeAudioVideoBattery |
+ : MediaLog::kWatchTimeAudioVideoAc, |
+ kWatchTime1); |
+ CycleReportingTimer(); |
+ |
+ // Invoke the test. |
+ test_callback_func(); |
+ |
+ const base::TimeDelta kExpectedWatchTime = |
+ TestFlags & kAccumulationContinuesAfterTest ? kWatchTime3 : kWatchTime2; |
+ |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kExpectedWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoSrc, kExpectedWatchTime); |
+ EXPECT_WATCH_TIME( |
+ TestFlags & kStartOnBattery ? MediaLog::kWatchTimeAudioVideoBattery |
+ : MediaLog::kWatchTimeAudioVideoAc, |
+ TestFlags & kFinalizePowerWatchTime ? kWatchTime2 : kExpectedWatchTime); |
+ |
+ // If we're not testing battery watch time, this is the end of the test. |
+ if (!(TestFlags & kTransitionPowerWatchTime)) { |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_.reset(); |
+ return; |
+ } |
+ |
+ ASSERT_TRUE(TestFlags & kAccumulationContinuesAfterTest) |
+ << "kTransitionPowerWatchTime tests must be done with " |
+ "kAccumulationContinuesAfterTest"; |
+ |
+ EXPECT_POWER_WATCH_TIME_FINALIZED(); |
+ CycleReportingTimer(); |
+ |
+ // Run one last cycle that is long enough to trigger a new watch time entry |
+ // on the opposite of the current power watch time graph; i.e. if we started |
+ // on battery we'll now record one for ac and vice versa. |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime4); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoSrc, kWatchTime4); |
+ EXPECT_WATCH_TIME(TestFlags & kStartOnBattery |
+ ? MediaLog::kWatchTimeAudioVideoAc |
+ : MediaLog::kWatchTimeAudioVideoBattery, |
+ kWatchTime4 - kWatchTime2); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_.reset(); |
+ } |
+ |
+ MOCK_METHOD0(GetCurrentMediaTime, base::TimeDelta()); |
+ |
+ base::TestMessageLoop message_loop_; |
+ scoped_refptr<testing::StrictMock<WatchTimeLogMonitor>> media_log_; |
+ std::unique_ptr<WatchTimeReporter> wtr_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(WatchTimeReporterTest); |
+}; |
+ |
+// Tests that watch time reporting is appropriately enabled or disabled. |
+TEST_F(WatchTimeReporterTest, WatchTimeReporter) { |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillRepeatedly(testing::Return(base::TimeDelta())); |
+ |
+ Initialize(false, true, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_FALSE(IsMonitoring()); |
+ |
+ Initialize(true, false, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_FALSE(IsMonitoring()); |
+ |
+ constexpr gfx::Size kSizeTooSmall = gfx::Size(100, 100); |
+ Initialize(true, true, true, true, kSizeTooSmall); |
+ wtr_->OnPlaying(); |
+ EXPECT_FALSE(IsMonitoring()); |
+ |
+ Initialize(true, true, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ |
+ Initialize(true, true, false, false, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ |
+ Initialize(true, true, true, false, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+} |
+ |
+// Tests that basic reporting for the all category works. |
+TEST_F(WatchTimeReporterTest, WatchTimeReporterBasic) { |
+ constexpr base::TimeDelta kWatchTimeEarly = base::TimeDelta::FromSeconds(5); |
+ constexpr base::TimeDelta kWatchTimeLate = base::TimeDelta::FromSeconds(10); |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTimeEarly)) |
+ .WillRepeatedly(testing::Return(kWatchTimeLate)); |
+ Initialize(true, true, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ |
+ // No log should have been generated yet since the message loop has not had |
+ // any chance to pump. |
+ CycleReportingTimer(); |
+ |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTimeLate); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTimeLate); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoEme, kWatchTimeLate); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoMse, kWatchTimeLate); |
+ CycleReportingTimer(); |
+} |
+// Tests that starting from a non-zero base works. |
+TEST_F(WatchTimeReporterTest, WatchTimeReporterNonZeroStart) { |
+ constexpr base::TimeDelta kWatchTime1 = base::TimeDelta::FromSeconds(5); |
+ constexpr base::TimeDelta kWatchTime2 = base::TimeDelta::FromSeconds(15); |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(kWatchTime1)) |
+ .WillRepeatedly(testing::Return(kWatchTime2)); |
+ Initialize(true, true, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ |
+ const base::TimeDelta kWatchTime = kWatchTime2 - kWatchTime1; |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoEme, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoMse, kWatchTime); |
+ CycleReportingTimer(); |
+} |
+ |
+// Tests that seeking causes an immediate finalization. |
+TEST_F(WatchTimeReporterTest, SeekFinalizes) { |
+ constexpr base::TimeDelta kWatchTime = base::TimeDelta::FromSeconds(10); |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime)); |
+ Initialize(true, true, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoEme, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoMse, kWatchTime); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_->OnSeeking(); |
+} |
+ |
+// Tests that seeking causes an immediate finalization, but does not trample a |
+// previously set finalize time. |
+TEST_F(WatchTimeReporterTest, SeekFinalizeDoesNotTramplePreviousFinalize) { |
+ constexpr base::TimeDelta kWatchTime = base::TimeDelta::FromSeconds(10); |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime)); |
+ Initialize(true, true, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoEme, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoMse, kWatchTime); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_->OnPaused(); |
+ wtr_->OnSeeking(); |
+} |
+ |
+// Tests that watch time is finalized upon destruction. |
+TEST_F(WatchTimeReporterTest, WatchTimeReporterFinalizeOnDestruction) { |
+ constexpr base::TimeDelta kWatchTime = base::TimeDelta::FromSeconds(10); |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime)); |
+ Initialize(true, true, true, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ |
+ // Finalize the histogram before any cycles of the timer have run. |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoEme, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoMse, kWatchTime); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_.reset(); |
+} |
+ |
+// Tests that watch time categories are mapped correctly. |
+TEST_F(WatchTimeReporterTest, WatchTimeCategoryMapping) { |
+ constexpr base::TimeDelta kWatchTime = base::TimeDelta::FromSeconds(10); |
+ |
+ // Verify ac, all, src |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime)); |
+ Initialize(true, true, false, false, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoSrc, kWatchTime); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_.reset(); |
+ |
+ // Verify ac, all, mse |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime)); |
+ Initialize(true, true, true, false, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoMse, kWatchTime); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_.reset(); |
+ |
+ // Verify ac, all, eme, src |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime)); |
+ Initialize(true, true, false, true, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ EXPECT_TRUE(IsMonitoring()); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAc, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoEme, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoSrc, kWatchTime); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_.reset(); |
+ |
+ // Verify all, battery, src |
+ EXPECT_CALL(*this, GetCurrentMediaTime()) |
+ .WillOnce(testing::Return(base::TimeDelta())) |
+ .WillOnce(testing::Return(kWatchTime)); |
+ Initialize(true, true, false, false, kSizeJustRight); |
+ wtr_->OnPlaying(); |
+ SetOnBatteryPower(true); |
+ EXPECT_TRUE(IsMonitoring()); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoAll, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoBattery, kWatchTime); |
+ EXPECT_WATCH_TIME(MediaLog::kWatchTimeAudioVideoSrc, kWatchTime); |
+ EXPECT_WATCH_TIME_FINALIZED(); |
+ wtr_.reset(); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, PlayPauseHysteresisContinuation) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest>([this]() { |
+ wtr_->OnPaused(); |
+ wtr_->OnPlaying(); |
+ }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, PlayPauseHysteresisFinalized) { |
+ RunHysteresisTest([this]() { wtr_->OnPaused(); }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnVolumeChangeHysteresisContinuation) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest>([this]() { |
+ wtr_->OnVolumeChange(0); |
+ wtr_->OnVolumeChange(1); |
+ }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnVolumeChangeHysteresisFinalized) { |
+ RunHysteresisTest([this]() { wtr_->OnVolumeChange(0); }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnShownHiddenHysteresisContinuation) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest>([this]() { |
+ wtr_->OnHidden(); |
+ wtr_->OnShown(); |
+ }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnShownHiddenHysteresisFinalized) { |
+ RunHysteresisTest([this]() { wtr_->OnHidden(); }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnPowerStateChangeHysteresisBatteryContinuation) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest | |
+ kFinalizeExitDoesNotRequireCurrentTime | kStartOnBattery>( |
+ [this]() { |
+ OnPowerStateChange(false); |
+ OnPowerStateChange(true); |
+ }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnPowerStateChangeHysteresisBatteryFinalized) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizePowerWatchTime | |
+ kStartOnBattery>([this]() { OnPowerStateChange(false); }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnPowerStateChangeHysteresisAcContinuation) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest | |
+ kFinalizeExitDoesNotRequireCurrentTime>([this]() { |
+ OnPowerStateChange(true); |
+ OnPowerStateChange(false); |
+ }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnPowerStateChangeHysteresisAcFinalized) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizePowerWatchTime>( |
+ [this]() { OnPowerStateChange(true); }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnPowerStateChangeBatteryTransitions) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizePowerWatchTime | |
+ kStartOnBattery | kTransitionPowerWatchTime>( |
+ [this]() { OnPowerStateChange(false); }); |
+} |
+ |
+TEST_F(WatchTimeReporterTest, OnPowerStateChangeAcTransitions) { |
+ RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizePowerWatchTime | |
+ kTransitionPowerWatchTime>( |
+ [this]() { OnPowerStateChange(true); }); |
+} |
+ |
+// Tests that the first finalize is the only one that matters. |
+TEST_F(WatchTimeReporterTest, HysteresisFinalizedWithEarliest) { |
+ RunHysteresisTest([this]() { |
+ wtr_->OnPaused(); |
+ |
+ // These subsequent "stop events" should do nothing since a finalize time |
+ // has already been selected. |
+ wtr_->OnHidden(); |
+ wtr_->OnVolumeChange(0); |
+ }); |
+} |
+ |
+// Tests that if a stop, stop, start sequence occurs, the middle stop is not |
+// undone and thus finalize still occurs. |
+TEST_F(WatchTimeReporterTest, HysteresisPartialExitStillFinalizes) { |
+ auto stop_event = [this](size_t i) { |
+ if (i == 0) |
+ wtr_->OnPaused(); |
+ else if (i == 1) |
+ wtr_->OnHidden(); |
+ else |
+ wtr_->OnVolumeChange(0); |
+ }; |
+ |
+ auto start_event = [this](size_t i) { |
+ if (i == 0) |
+ wtr_->OnPlaying(); |
+ else if (i == 1) |
+ wtr_->OnShown(); |
+ else |
+ wtr_->OnVolumeChange(1); |
+ }; |
+ |
+ for (size_t i = 0; i < 3; ++i) { |
+ for (size_t j = 0; j < 3; ++j) { |
+ if (i == j) |
+ continue; |
+ |
+ RunHysteresisTest<kFinalizeInterleavedStartEvent>( |
+ [i, j, start_event, stop_event]() { |
+ stop_event(i); |
+ stop_event(j); |
+ start_event(i); |
+ }); |
+ } |
+ } |
+} |
+ |
+} // namespace media |