| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <tuple> | 5 #include <tuple> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "base/test/histogram_tester.h" | 12 #include "base/test/histogram_tester.h" |
| 13 #include "base/test/simple_test_tick_clock.h" | 13 #include "base/test/simple_test_tick_clock.h" |
| 14 #include "base/threading/thread_task_runner_handle.h" | 14 #include "base/threading/thread_task_runner_handle.h" |
| 15 #include "content/common/media/media_player_delegate_messages.h" | 15 #include "content/common/media/media_player_delegate_messages.h" |
| 16 #include "content/public/renderer/render_view.h" | 16 #include "content/public/renderer/render_view.h" |
| 17 #include "content/public/test/render_view_test.h" | 17 #include "content/public/test/render_view_test.h" |
| 18 #include "content/renderer/media/renderer_webmediaplayer_delegate.h" | 18 #include "content/renderer/media/renderer_webmediaplayer_delegate.h" |
| 19 #include "content/renderer/render_process.h" | 19 #include "content/renderer/render_process.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 22 |
| 23 using testing::NiceMock; |
| 24 using testing::Return; |
| 25 using testing::StrictMock; |
| 26 |
| 23 namespace media { | 27 namespace media { |
| 24 | 28 |
| 29 namespace { |
| 30 constexpr base::TimeDelta kIdleTimeout = base::TimeDelta::FromSeconds(1); |
| 31 } |
| 32 |
| 25 ACTION_P(RunClosure, closure) { | 33 ACTION_P(RunClosure, closure) { |
| 26 closure.Run(); | 34 closure.Run(); |
| 35 return true; |
| 27 } | 36 } |
| 28 | 37 |
| 29 class MockWebMediaPlayerDelegateObserver | 38 class MockWebMediaPlayerDelegateObserver |
| 30 : public WebMediaPlayerDelegate::Observer { | 39 : public WebMediaPlayerDelegate::Observer { |
| 31 public: | 40 public: |
| 32 MockWebMediaPlayerDelegateObserver() {} | 41 MockWebMediaPlayerDelegateObserver() {} |
| 33 ~MockWebMediaPlayerDelegateObserver() {} | 42 ~MockWebMediaPlayerDelegateObserver() {} |
| 34 | 43 |
| 35 // WebMediaPlayerDelegate::Observer implementation. | 44 // WebMediaPlayerDelegate::Observer implementation. |
| 36 MOCK_METHOD0(OnHidden, void()); | 45 MOCK_METHOD0(OnHidden, void()); |
| 37 MOCK_METHOD0(OnShown, void()); | 46 MOCK_METHOD0(OnShown, void()); |
| 38 MOCK_METHOD1(OnSuspendRequested, void(bool)); | 47 MOCK_METHOD1(OnSuspendRequested, bool(bool)); |
| 39 MOCK_METHOD0(OnPlay, void()); | 48 MOCK_METHOD0(OnPlay, void()); |
| 40 MOCK_METHOD0(OnPause, void()); | 49 MOCK_METHOD0(OnPause, void()); |
| 41 MOCK_METHOD1(OnVolumeMultiplierUpdate, void(double)); | 50 MOCK_METHOD1(OnVolumeMultiplierUpdate, void(double)); |
| 42 }; | 51 }; |
| 43 | 52 |
| 44 class RendererWebMediaPlayerDelegateTest : public content::RenderViewTest { | 53 class RendererWebMediaPlayerDelegateTest : public content::RenderViewTest { |
| 45 public: | 54 public: |
| 46 RendererWebMediaPlayerDelegateTest() {} | 55 RendererWebMediaPlayerDelegateTest() {} |
| 47 ~RendererWebMediaPlayerDelegateTest() override {} | 56 ~RendererWebMediaPlayerDelegateTest() override {} |
| 48 | 57 |
| 49 void SetUp() override { | 58 void SetUp() override { |
| 50 RenderViewTest::SetUp(); | 59 RenderViewTest::SetUp(); |
| 60 // Start the tick clock off at a non-null value. |
| 61 tick_clock_.Advance(base::TimeDelta::FromSeconds(1234)); |
| 51 delegate_manager_.reset( | 62 delegate_manager_.reset( |
| 52 new RendererWebMediaPlayerDelegate(view_->GetMainRenderFrame())); | 63 new RendererWebMediaPlayerDelegate(view_->GetMainRenderFrame())); |
| 64 delegate_manager_->SetIdleCleanupParamsForTesting(kIdleTimeout, |
| 65 &tick_clock_, false); |
| 53 } | 66 } |
| 54 | 67 |
| 55 void TearDown() override { | 68 void TearDown() override { |
| 56 // Destruct the controller prior to any other tear down to avoid out of | |
| 57 // order destruction relative to the test render frame. | |
| 58 delegate_manager_.reset(); | 69 delegate_manager_.reset(); |
| 59 RenderViewTest::TearDown(); | 70 RenderViewTest::TearDown(); |
| 60 } | 71 } |
| 61 | 72 |
| 62 protected: | 73 protected: |
| 63 IPC::TestSink& test_sink() { return render_thread_->sink(); } | 74 IPC::TestSink& test_sink() { return render_thread_->sink(); } |
| 64 | 75 |
| 65 bool HasPlayingVideo(int delegate_id) { | 76 bool HasPlayingVideo(int delegate_id) { |
| 66 return delegate_manager_->playing_videos_.count(delegate_id); | 77 return delegate_manager_->playing_videos_.count(delegate_id); |
| 67 } | 78 } |
| 68 | 79 |
| 69 void SetPlayingBackgroundVideo(bool is_playing) { | 80 void SetPlayingBackgroundVideo(bool is_playing) { |
| 70 delegate_manager_->is_playing_background_video_ = is_playing; | 81 delegate_manager_->is_playing_background_video_ = is_playing; |
| 71 } | 82 } |
| 72 | 83 |
| 73 void CallOnMediaDelegatePlay(int delegate_id) { | 84 void CallOnMediaDelegatePlay(int delegate_id) { |
| 74 delegate_manager_->OnMediaDelegatePlay(delegate_id); | 85 delegate_manager_->OnMediaDelegatePlay(delegate_id); |
| 75 } | 86 } |
| 76 | 87 |
| 77 void CallOnMediaDelegatePause(int delegate_id) { | 88 void CallOnMediaDelegatePause(int delegate_id) { |
| 78 delegate_manager_->OnMediaDelegatePause(delegate_id); | 89 delegate_manager_->OnMediaDelegatePause(delegate_id); |
| 79 } | 90 } |
| 80 | 91 |
| 92 void SetIsLowEndDeviceForTesting() { |
| 93 delegate_manager_->SetIdleCleanupParamsForTesting(kIdleTimeout, |
| 94 &tick_clock_, true); |
| 95 } |
| 96 |
| 81 std::unique_ptr<RendererWebMediaPlayerDelegate> delegate_manager_; | 97 std::unique_ptr<RendererWebMediaPlayerDelegate> delegate_manager_; |
| 98 StrictMock<MockWebMediaPlayerDelegateObserver> observer_1_, observer_2_, |
| 99 observer_3_; |
| 100 base::SimpleTestTickClock tick_clock_; |
| 82 | 101 |
| 83 private: | 102 private: |
| 84 DISALLOW_COPY_AND_ASSIGN(RendererWebMediaPlayerDelegateTest); | 103 DISALLOW_COPY_AND_ASSIGN(RendererWebMediaPlayerDelegateTest); |
| 85 }; | 104 }; |
| 86 | 105 |
| 87 TEST_F(RendererWebMediaPlayerDelegateTest, SendsMessagesCorrectly) { | 106 TEST_F(RendererWebMediaPlayerDelegateTest, SendsMessagesCorrectly) { |
| 88 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer; | 107 StrictMock<MockWebMediaPlayerDelegateObserver> observer; |
| 89 const int delegate_id = delegate_manager_->AddObserver(&observer); | 108 const int delegate_id = delegate_manager_->AddObserver(&observer); |
| 90 | 109 |
| 91 // Verify the playing message. | 110 // Verify the playing message. |
| 92 { | 111 { |
| 93 const bool kHasVideo = true, kHasAudio = false, kIsRemote = false; | 112 const bool kHasVideo = true, kHasAudio = false, kIsRemote = false; |
| 94 const media::MediaContentType kMediaContentType = | 113 const media::MediaContentType kMediaContentType = |
| 95 media::MediaContentType::Transient; | 114 media::MediaContentType::Transient; |
| 96 delegate_manager_->DidPlay(delegate_id, kHasVideo, kHasAudio, kIsRemote, | 115 delegate_manager_->DidPlay(delegate_id, kHasVideo, kHasAudio, kIsRemote, |
| 97 kMediaContentType); | 116 kMediaContentType); |
| 98 | 117 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 delegate_manager_->PlayerGone(delegate_id); | 150 delegate_manager_->PlayerGone(delegate_id); |
| 132 const IPC::Message* msg = test_sink().GetUniqueMessageMatching( | 151 const IPC::Message* msg = test_sink().GetUniqueMessageMatching( |
| 133 MediaPlayerDelegateHostMsg_OnMediaDestroyed::ID); | 152 MediaPlayerDelegateHostMsg_OnMediaDestroyed::ID); |
| 134 ASSERT_TRUE(msg); | 153 ASSERT_TRUE(msg); |
| 135 | 154 |
| 136 std::tuple<int> result; | 155 std::tuple<int> result; |
| 137 ASSERT_TRUE( | 156 ASSERT_TRUE( |
| 138 MediaPlayerDelegateHostMsg_OnMediaDestroyed::Read(msg, &result)); | 157 MediaPlayerDelegateHostMsg_OnMediaDestroyed::Read(msg, &result)); |
| 139 EXPECT_EQ(delegate_id, std::get<0>(result)); | 158 EXPECT_EQ(delegate_id, std::get<0>(result)); |
| 140 } | 159 } |
| 141 | |
| 142 delegate_manager_->RemoveObserver(delegate_id); | |
| 143 } | 160 } |
| 144 | 161 |
| 145 TEST_F(RendererWebMediaPlayerDelegateTest, DeliversObserverNotifications) { | 162 TEST_F(RendererWebMediaPlayerDelegateTest, DeliversObserverNotifications) { |
| 146 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer; | 163 const int delegate_id = delegate_manager_->AddObserver(&observer_1_); |
| 147 const int delegate_id = delegate_manager_->AddObserver(&observer); | |
| 148 | 164 |
| 149 EXPECT_CALL(observer, OnHidden()); | 165 EXPECT_CALL(observer_1_, OnHidden()); |
| 150 delegate_manager_->WasHidden(); | 166 delegate_manager_->WasHidden(); |
| 151 | 167 |
| 152 EXPECT_CALL(observer, OnShown()); | 168 EXPECT_CALL(observer_1_, OnShown()); |
| 153 delegate_manager_->WasShown(); | 169 delegate_manager_->WasShown(); |
| 154 | 170 |
| 155 EXPECT_CALL(observer, OnPause()); | 171 EXPECT_CALL(observer_1_, OnPause()); |
| 156 MediaPlayerDelegateMsg_Pause pause_msg(0, delegate_id); | 172 MediaPlayerDelegateMsg_Pause pause_msg(0, delegate_id); |
| 157 delegate_manager_->OnMessageReceived(pause_msg); | 173 delegate_manager_->OnMessageReceived(pause_msg); |
| 158 | 174 |
| 159 EXPECT_CALL(observer, OnPlay()); | 175 EXPECT_CALL(observer_1_, OnPlay()); |
| 160 MediaPlayerDelegateMsg_Play play_msg(0, delegate_id); | 176 MediaPlayerDelegateMsg_Play play_msg(0, delegate_id); |
| 161 delegate_manager_->OnMessageReceived(play_msg); | 177 delegate_manager_->OnMessageReceived(play_msg); |
| 162 | 178 |
| 163 const double kTestMultiplier = 0.5; | 179 const double kTestMultiplier = 0.5; |
| 164 EXPECT_CALL(observer, OnVolumeMultiplierUpdate(kTestMultiplier)); | 180 EXPECT_CALL(observer_1_, OnVolumeMultiplierUpdate(kTestMultiplier)); |
| 165 MediaPlayerDelegateMsg_UpdateVolumeMultiplier volume_msg(0, delegate_id, | 181 MediaPlayerDelegateMsg_UpdateVolumeMultiplier volume_msg(0, delegate_id, |
| 166 kTestMultiplier); | 182 kTestMultiplier); |
| 167 delegate_manager_->OnMessageReceived(volume_msg); | 183 delegate_manager_->OnMessageReceived(volume_msg); |
| 168 | 184 |
| 169 EXPECT_CALL(observer, OnSuspendRequested(true)); | 185 EXPECT_CALL(observer_1_, OnSuspendRequested(true)); |
| 170 MediaPlayerDelegateMsg_SuspendAllMediaPlayers suspend_msg(0); | 186 MediaPlayerDelegateMsg_SuspendAllMediaPlayers suspend_msg(0); |
| 171 delegate_manager_->OnMessageReceived(suspend_msg); | 187 delegate_manager_->OnMessageReceived(suspend_msg); |
| 188 } |
| 172 | 189 |
| 173 delegate_manager_->RemoveObserver(delegate_id); | 190 TEST_F(RendererWebMediaPlayerDelegateTest, TheTimerIsInitiallyStopped) { |
| 191 ASSERT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); |
| 192 } |
| 193 |
| 194 TEST_F(RendererWebMediaPlayerDelegateTest, AddingAnObserverStartsTheTimer) { |
| 195 delegate_manager_->AddObserver(&observer_1_); |
| 196 ASSERT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); |
| 197 } |
| 198 |
| 199 TEST_F(RendererWebMediaPlayerDelegateTest, RemovingAllObserversStopsTheTimer) { |
| 200 delegate_manager_->RemoveObserver( |
| 201 delegate_manager_->AddObserver(&observer_1_)); |
| 202 ASSERT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); |
| 203 } |
| 204 |
| 205 TEST_F(RendererWebMediaPlayerDelegateTest, PlayingDelegatesAreNotIdle) { |
| 206 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1_); |
| 207 delegate_manager_->DidPlay(delegate_id_1, true, true, false, |
| 208 media::MediaContentType::Persistent); |
| 209 ASSERT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); |
| 174 } | 210 } |
| 175 | 211 |
| 176 TEST_F(RendererWebMediaPlayerDelegateTest, PlaySuspendsLowEndIdleDelegates) { | 212 TEST_F(RendererWebMediaPlayerDelegateTest, PlaySuspendsLowEndIdleDelegates) { |
| 177 // Start the tick clock off at a non-null value. | 213 SetIsLowEndDeviceForTesting(); |
| 178 base::SimpleTestTickClock tick_clock; | |
| 179 tick_clock.Advance(base::TimeDelta::FromSeconds(1234)); | |
| 180 | 214 |
| 181 const base::TimeDelta kIdleTimeout = base::TimeDelta::FromSeconds(10); | 215 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1_); |
| 182 delegate_manager_->SetIdleCleanupParamsForTesting(kIdleTimeout, &tick_clock, | 216 delegate_manager_->AddObserver(&observer_2_); |
| 183 true); | |
| 184 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 185 | |
| 186 // Add two observers, both of which should keep the idle timer running. | |
| 187 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_1; | |
| 188 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1); | |
| 189 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 190 | |
| 191 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_2; | |
| 192 const int delegate_id_2 = delegate_manager_->AddObserver(&observer_2); | |
| 193 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 194 | 217 |
| 195 // Calling play on the first player should suspend the other idle player. | 218 // Calling play on the first player should suspend the other idle player. |
| 196 EXPECT_CALL(observer_2, OnSuspendRequested(false)) | 219 EXPECT_CALL(observer_2_, OnSuspendRequested(false)); |
| 197 .WillOnce(RunClosure(base::Bind( | 220 tick_clock_.Advance(base::TimeDelta::FromMicroseconds(1)); |
| 198 &RendererWebMediaPlayerDelegate::PlayerGone, | |
| 199 base::Unretained(delegate_manager_.get()), delegate_id_2))); | |
| 200 base::RunLoop run_loop; | |
| 201 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
| 202 run_loop.QuitClosure()); | |
| 203 tick_clock.Advance(base::TimeDelta::FromMicroseconds(1)); | |
| 204 delegate_manager_->DidPlay(delegate_id_1, true, true, false, | 221 delegate_manager_->DidPlay(delegate_id_1, true, true, false, |
| 205 media::MediaContentType::Persistent); | 222 media::MediaContentType::Persistent); |
| 206 run_loop.Run(); | |
| 207 } | 223 } |
| 208 | 224 |
| 209 TEST_F(RendererWebMediaPlayerDelegateTest, MaxLowEndIdleDelegates) { | 225 TEST_F(RendererWebMediaPlayerDelegateTest, MaxLowEndIdleDelegates) { |
| 210 // Start the tick clock off at a non-null value. | 226 SetIsLowEndDeviceForTesting(); |
| 211 base::SimpleTestTickClock tick_clock; | |
| 212 tick_clock.Advance(base::TimeDelta::FromSeconds(1234)); | |
| 213 | 227 |
| 214 const base::TimeDelta kIdleTimeout = base::TimeDelta::FromSeconds(10); | 228 delegate_manager_->AddObserver(&observer_1_); |
| 215 delegate_manager_->SetIdleCleanupParamsForTesting(kIdleTimeout, &tick_clock, | 229 delegate_manager_->AddObserver(&observer_2_); |
| 216 true); | |
| 217 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 218 | |
| 219 // Add two observers, both of which should keep the idle timer running. | |
| 220 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_1; | |
| 221 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1); | |
| 222 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 223 | |
| 224 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_2; | |
| 225 const int delegate_id_2 = delegate_manager_->AddObserver(&observer_2); | |
| 226 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 227 | |
| 228 tick_clock.Advance(base::TimeDelta::FromMicroseconds(1)); | |
| 229 | 230 |
| 230 // Just adding a third idle observer should suspend the others. | 231 // Just adding a third idle observer should suspend the others. |
| 231 EXPECT_CALL(observer_1, OnSuspendRequested(false)) | 232 EXPECT_CALL(observer_1_, OnSuspendRequested(false)); |
| 232 .WillOnce(RunClosure(base::Bind( | 233 EXPECT_CALL(observer_2_, OnSuspendRequested(false)); |
| 233 &RendererWebMediaPlayerDelegate::PlayerGone, | 234 tick_clock_.Advance(base::TimeDelta::FromMicroseconds(1)); |
| 234 base::Unretained(delegate_manager_.get()), delegate_id_1))); | 235 delegate_manager_->AddObserver(&observer_3_); |
| 235 EXPECT_CALL(observer_2, OnSuspendRequested(false)) | |
| 236 .WillOnce(RunClosure(base::Bind( | |
| 237 &RendererWebMediaPlayerDelegate::PlayerGone, | |
| 238 base::Unretained(delegate_manager_.get()), delegate_id_2))); | |
| 239 | |
| 240 base::RunLoop run_loop; | |
| 241 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
| 242 run_loop.QuitClosure()); | |
| 243 | |
| 244 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_3; | |
| 245 delegate_manager_->AddObserver(&observer_3); | |
| 246 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 247 | |
| 248 run_loop.Run(); | |
| 249 } | 236 } |
| 250 | 237 |
| 251 TEST_F(RendererWebMediaPlayerDelegateTest, ReentrantIdleDelegates) { | 238 // Make sure it's safe to call DidPause(), which modifies the idle delegate |
| 252 // Start the tick clock off at a non-null value. | 239 // list, from OnSuspendRequested(), which iterates over the idle delegate list. |
| 253 base::SimpleTestTickClock tick_clock; | 240 TEST_F(RendererWebMediaPlayerDelegateTest, ReentrantDelegateCallsAreSafe) { |
| 254 tick_clock.Advance(base::TimeDelta::FromSeconds(1234)); | 241 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1_); |
| 255 | 242 EXPECT_CALL(observer_1_, OnSuspendRequested(false)) |
| 256 const base::TimeDelta kIdleTimeout = base::TimeDelta::FromSeconds(10); | |
| 257 delegate_manager_->SetIdleCleanupParamsForTesting(kIdleTimeout, &tick_clock, | |
| 258 true); | |
| 259 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 260 | |
| 261 // Add two observers, both of which should keep the idle timer running. | |
| 262 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_1; | |
| 263 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1); | |
| 264 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 265 | |
| 266 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_2; | |
| 267 const int delegate_id_2 = delegate_manager_->AddObserver(&observer_2); | |
| 268 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 269 | |
| 270 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_3; | |
| 271 EXPECT_CALL(observer_1, OnSuspendRequested(false)) | |
| 272 .WillOnce(RunClosure(base::Bind(&RendererWebMediaPlayerDelegate::DidPause, | 243 .WillOnce(RunClosure(base::Bind(&RendererWebMediaPlayerDelegate::DidPause, |
| 273 base::Unretained(delegate_manager_.get()), | 244 base::Unretained(delegate_manager_.get()), |
| 274 delegate_id_1, false))); | 245 delegate_id_1, false))); |
| 275 EXPECT_CALL(observer_2, OnSuspendRequested(false)) | 246 // Run an idle cleanup. |
| 276 .WillOnce(RunClosure(base::Bind(&RendererWebMediaPlayerDelegate::DidPause, | 247 tick_clock_.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); |
| 277 base::Unretained(delegate_manager_.get()), | 248 base::RunLoop().RunUntilIdle(); |
| 278 delegate_id_2, false))); | 249 } |
| 279 base::RunLoop run_loop; | 250 |
| 280 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 251 TEST_F(RendererWebMediaPlayerDelegateTest, |
| 281 run_loop.QuitClosure()); | 252 SuspendRequestsAreOnlySentOnceIfHandled) { |
| 282 tick_clock.Advance(base::TimeDelta::FromMicroseconds(1)); | 253 delegate_manager_->AddObserver(&observer_1_); |
| 283 // Adding the third observer should force idle cleanup. | 254 // Return true from OnSuspendRequested() to indicate that it was handled. So |
| 284 delegate_manager_->AddObserver(&observer_3); | 255 // even though the player did not call PlayerGone() it should be removed from |
| 285 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | 256 // future idle cleanup polls. |
| 286 run_loop.Run(); | 257 EXPECT_CALL(observer_1_, OnSuspendRequested(false)).WillOnce(Return(true)); |
| 258 tick_clock_.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); |
| 259 base::RunLoop().RunUntilIdle(); |
| 260 } |
| 261 |
| 262 TEST_F(RendererWebMediaPlayerDelegateTest, |
| 263 SuspendRequestsAreSentAgainIfNotHandled) { |
| 264 delegate_manager_->AddObserver(&observer_1_); |
| 265 // Return false from OnSuspendRequested() to indicate that it was not handled. |
| 266 // The observer should get another OnSuspendRequested. |
| 267 EXPECT_CALL(observer_1_, OnSuspendRequested(false)) |
| 268 .WillOnce(Return(false)) |
| 269 .WillOnce(Return(true)); |
| 270 tick_clock_.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); |
| 271 base::RunLoop().RunUntilIdle(); |
| 287 } | 272 } |
| 288 | 273 |
| 289 TEST_F(RendererWebMediaPlayerDelegateTest, IdleDelegatesAreSuspended) { | 274 TEST_F(RendererWebMediaPlayerDelegateTest, IdleDelegatesAreSuspended) { |
| 290 // Start the tick clock off at a non-null value. | 275 // Add one non-idle observer and one idle observer. |
| 291 base::SimpleTestTickClock tick_clock; | 276 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1_); |
| 292 tick_clock.Advance(base::TimeDelta::FromSeconds(1234)); | |
| 293 | |
| 294 const base::TimeDelta kIdleTimeout = base::TimeDelta::FromSeconds(2); | |
| 295 delegate_manager_->SetIdleCleanupParamsForTesting(kIdleTimeout, &tick_clock, | |
| 296 false); | |
| 297 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 298 | |
| 299 // Just adding an observer should start the idle timer. | |
| 300 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_1; | |
| 301 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1); | |
| 302 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 303 | |
| 304 // Starting playback should not have an idle timer. | |
| 305 delegate_manager_->DidPlay(delegate_id_1, true, true, false, | 277 delegate_manager_->DidPlay(delegate_id_1, true, true, false, |
| 306 media::MediaContentType::Persistent); | 278 media::MediaContentType::Persistent); |
| 307 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | 279 delegate_manager_->AddObserver(&observer_2_); |
| 308 | 280 |
| 309 // Never calling DidPlay() but calling DidPause() should count as idle. | 281 // The idle cleanup task should suspend the second delegate while the first is |
| 310 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_2; | 282 // kept alive. |
| 311 const int delegate_id_2 = delegate_manager_->AddObserver(&observer_2); | |
| 312 delegate_manager_->DidPause(delegate_id_2, false); | |
| 313 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 314 | |
| 315 // Adding the observer should instantly queue the timeout task, once run the | |
| 316 // second delegate should be expired while the first is kept alive. | |
| 317 { | 283 { |
| 318 EXPECT_CALL(observer_2, OnSuspendRequested(false)) | 284 EXPECT_CALL(observer_2_, OnSuspendRequested(false)).WillOnce(Return(true)); |
| 319 .WillOnce(RunClosure(base::Bind( | 285 tick_clock_.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); |
| 320 &RendererWebMediaPlayerDelegate::PlayerGone, | 286 base::RunLoop().RunUntilIdle(); |
| 321 base::Unretained(delegate_manager_.get()), delegate_id_2))); | |
| 322 base::RunLoop run_loop; | |
| 323 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
| 324 run_loop.QuitClosure()); | |
| 325 tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); | |
| 326 run_loop.Run(); | |
| 327 } | 287 } |
| 328 | 288 |
| 329 // Pausing should count as idle if playback didn't reach end of stream, but | 289 // Pausing should count as idle if playback didn't reach end of stream, but |
| 330 // in this case the player will not remove the MediaSession. | 290 // in this case the player will not remove the MediaSession. |
| 331 delegate_manager_->DidPause(delegate_id_1, false /* reached_end_of_stream */); | 291 delegate_manager_->DidPause(delegate_id_1, false /* reached_end_of_stream */); |
| 332 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_3; | 292 const int delegate_id_3 = delegate_manager_->AddObserver(&observer_3_); |
| 333 const int delegate_id_3 = delegate_manager_->AddObserver(&observer_3); | |
| 334 delegate_manager_->DidPlay(delegate_id_3, true, true, false, | 293 delegate_manager_->DidPlay(delegate_id_3, true, true, false, |
| 335 media::MediaContentType::Persistent); | 294 media::MediaContentType::Persistent); |
| 336 | 295 |
| 337 // Adding the observer should instantly queue the timeout task, once run no | 296 // Adding the observer should instantly queue the timeout task. Once run only |
| 338 // delegates should have been expired. | 297 // the first player should be suspended. |
| 339 { | 298 { |
| 340 EXPECT_CALL(observer_1, OnSuspendRequested(false)) | 299 EXPECT_CALL(observer_1_, OnSuspendRequested(false)).WillOnce(Return(true)); |
| 341 .Times(testing::AtLeast(1)); | |
| 342 base::RunLoop run_loop; | 300 base::RunLoop run_loop; |
| 343 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 301 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 344 run_loop.QuitClosure()); | 302 run_loop.QuitClosure()); |
| 345 tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); | 303 tick_clock_.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); |
| 346 run_loop.Run(); | 304 run_loop.Run(); |
| 347 } | 305 } |
| 348 | 306 |
| 349 delegate_manager_->DidPlay(delegate_id_1, true, true, false, | 307 delegate_manager_->DidPlay(delegate_id_1, true, true, false, |
| 350 media::MediaContentType::Persistent); | 308 media::MediaContentType::Persistent); |
| 351 | 309 |
| 352 // Pausing after reaching end of stream should count as idle. | 310 // Pausing after reaching end of stream should count as idle. |
| 353 delegate_manager_->DidPause(delegate_id_1, true /* reached_end_of_stream */); | 311 delegate_manager_->DidPause(delegate_id_1, true /* reached_end_of_stream */); |
| 354 | 312 |
| 355 // Once the timeout task runs the first delegate should be expired while the | 313 // Once the timeout task runs the first delegate should be suspended while the |
| 356 // third is kept alive. | 314 // third is kept alive. |
| 357 { | 315 { |
| 358 EXPECT_CALL(observer_1, OnSuspendRequested(false)) | 316 EXPECT_CALL(observer_1_, OnSuspendRequested(false)).WillOnce(Return(true)); |
| 359 .WillOnce(RunClosure(base::Bind( | |
| 360 &RendererWebMediaPlayerDelegate::PlayerGone, | |
| 361 base::Unretained(delegate_manager_.get()), delegate_id_1))); | |
| 362 base::RunLoop run_loop; | 317 base::RunLoop run_loop; |
| 363 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 318 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 364 run_loop.QuitClosure()); | 319 run_loop.QuitClosure()); |
| 365 tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); | 320 tick_clock_.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); |
| 366 run_loop.Run(); | 321 run_loop.Run(); |
| 367 } | 322 } |
| 368 | |
| 369 delegate_manager_->RemoveObserver(delegate_id_1); | |
| 370 delegate_manager_->RemoveObserver(delegate_id_2); | |
| 371 delegate_manager_->RemoveObserver(delegate_id_3); | |
| 372 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 373 } | |
| 374 | |
| 375 TEST_F(RendererWebMediaPlayerDelegateTest, IdleDelegatesIgnoresSuspendRequest) { | |
| 376 // Start the tick clock off at a non-null value. | |
| 377 base::SimpleTestTickClock tick_clock; | |
| 378 tick_clock.Advance(base::TimeDelta::FromSeconds(1234)); | |
| 379 | |
| 380 const base::TimeDelta kIdleTimeout = base::TimeDelta::FromSeconds(2); | |
| 381 delegate_manager_->SetIdleCleanupParamsForTesting(kIdleTimeout, &tick_clock, | |
| 382 false); | |
| 383 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 384 | |
| 385 testing::StrictMock<MockWebMediaPlayerDelegateObserver> observer_1; | |
| 386 const int delegate_id_1 = delegate_manager_->AddObserver(&observer_1); | |
| 387 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 388 | |
| 389 // Calling DidPause() should instantly queue the timeout task. | |
| 390 delegate_manager_->DidPause(delegate_id_1, false); | |
| 391 EXPECT_TRUE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 392 | |
| 393 // Wait for the suspend request, but don't call PlayerGone(). | |
| 394 EXPECT_CALL(observer_1, OnSuspendRequested(false)).Times(testing::AtLeast(1)); | |
| 395 base::RunLoop run_loop; | |
| 396 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
| 397 run_loop.QuitClosure()); | |
| 398 tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1)); | |
| 399 run_loop.Run(); | |
| 400 | |
| 401 // Even though the player did not call PlayerGone() it should be removed from | |
| 402 // future idle cleanup polls. | |
| 403 EXPECT_FALSE(delegate_manager_->IsIdleCleanupTimerRunningForTesting()); | |
| 404 delegate_manager_->RemoveObserver(delegate_id_1); | |
| 405 } | 323 } |
| 406 | 324 |
| 407 TEST_F(RendererWebMediaPlayerDelegateTest, PlayingVideosSet) { | 325 TEST_F(RendererWebMediaPlayerDelegateTest, PlayingVideosSet) { |
| 408 MockWebMediaPlayerDelegateObserver observer; | 326 int delegate_id = delegate_manager_->AddObserver(&observer_1_); |
| 409 int delegate_id = delegate_manager_->AddObserver(&observer); | |
| 410 EXPECT_FALSE(HasPlayingVideo(delegate_id)); | 327 EXPECT_FALSE(HasPlayingVideo(delegate_id)); |
| 411 | 328 |
| 412 // Playing a local video adds it to the set. | 329 // Playing a local video adds it to the set. |
| 413 delegate_manager_->DidPlay(delegate_id, true, true, false, | 330 delegate_manager_->DidPlay(delegate_id, true, true, false, |
| 414 MediaContentType::Persistent); | 331 MediaContentType::Persistent); |
| 415 EXPECT_TRUE(HasPlayingVideo(delegate_id)); | 332 EXPECT_TRUE(HasPlayingVideo(delegate_id)); |
| 416 | 333 |
| 417 // Pause doesn't remove the video from the set. | 334 // Pause doesn't remove the video from the set. |
| 418 delegate_manager_->DidPause(delegate_id, false); | 335 delegate_manager_->DidPause(delegate_id, false); |
| 419 EXPECT_TRUE(HasPlayingVideo(delegate_id)); | 336 EXPECT_TRUE(HasPlayingVideo(delegate_id)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 446 EXPECT_FALSE(HasPlayingVideo(delegate_id)); | 363 EXPECT_FALSE(HasPlayingVideo(delegate_id)); |
| 447 | 364 |
| 448 // Removing the observer also removes the video from the set. | 365 // Removing the observer also removes the video from the set. |
| 449 delegate_manager_->DidPlay(delegate_id, true, true, false, | 366 delegate_manager_->DidPlay(delegate_id, true, true, false, |
| 450 MediaContentType::Persistent); | 367 MediaContentType::Persistent); |
| 451 delegate_manager_->RemoveObserver(delegate_id); | 368 delegate_manager_->RemoveObserver(delegate_id); |
| 452 EXPECT_FALSE(HasPlayingVideo(delegate_id)); | 369 EXPECT_FALSE(HasPlayingVideo(delegate_id)); |
| 453 } | 370 } |
| 454 | 371 |
| 455 TEST_F(RendererWebMediaPlayerDelegateTest, IsPlayingBackgroundVideo) { | 372 TEST_F(RendererWebMediaPlayerDelegateTest, IsPlayingBackgroundVideo) { |
| 456 testing::NiceMock<MockWebMediaPlayerDelegateObserver> observer; | 373 NiceMock<MockWebMediaPlayerDelegateObserver> observer; |
| 457 int delegate_id = delegate_manager_->AddObserver(&observer); | 374 int delegate_id = delegate_manager_->AddObserver(&observer); |
| 458 EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); | 375 EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); |
| 459 | 376 |
| 460 // Showing the frame always clears the flag. | 377 // Showing the frame always clears the flag. |
| 461 SetPlayingBackgroundVideo(true); | 378 SetPlayingBackgroundVideo(true); |
| 462 delegate_manager_->WasShown(); | 379 delegate_manager_->WasShown(); |
| 463 EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); | 380 EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); |
| 464 | 381 |
| 465 // Pausing anything other than a local playing video doesn't affect the flag. | 382 // Pausing anything other than a local playing video doesn't affect the flag. |
| 466 SetPlayingBackgroundVideo(true); | 383 SetPlayingBackgroundVideo(true); |
| 467 CallOnMediaDelegatePause(delegate_id); | 384 CallOnMediaDelegatePause(delegate_id); |
| 468 EXPECT_TRUE(delegate_manager_->IsPlayingBackgroundVideo()); | 385 EXPECT_TRUE(delegate_manager_->IsPlayingBackgroundVideo()); |
| 469 | 386 |
| 470 // Pausing a currently playing video does clears the flag. | 387 // Pausing a currently playing video clears the flag. |
| 471 delegate_manager_->DidPlay(delegate_id, true, true, false, | 388 delegate_manager_->DidPlay(delegate_id, true, true, false, |
| 472 MediaContentType::Persistent); | 389 MediaContentType::Persistent); |
| 473 CallOnMediaDelegatePause(delegate_id); | 390 CallOnMediaDelegatePause(delegate_id); |
| 474 EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); | 391 EXPECT_FALSE(delegate_manager_->IsPlayingBackgroundVideo()); |
| 475 | 392 |
| 476 // TODO(avayvod): this test can't mock IsHidden() method. | 393 // TODO(avayvod): this test can't mock the IsHidden() method. |
| 477 // Just test that the value changes or doesn't depending on whether the video | 394 // Just test that the value changes or doesn't depending on whether the video |
| 478 // is currently playing. | 395 // is currently playing. |
| 479 bool old_value = !delegate_manager_->IsHidden(); | 396 bool old_value = !delegate_manager_->IsHidden(); |
| 480 SetPlayingBackgroundVideo(old_value); | 397 SetPlayingBackgroundVideo(old_value); |
| 481 delegate_manager_->DidPause(delegate_id, true); | 398 delegate_manager_->DidPause(delegate_id, true); |
| 482 CallOnMediaDelegatePlay(delegate_id); | 399 CallOnMediaDelegatePlay(delegate_id); |
| 483 EXPECT_EQ(old_value, delegate_manager_->IsPlayingBackgroundVideo()); | 400 EXPECT_EQ(old_value, delegate_manager_->IsPlayingBackgroundVideo()); |
| 484 | 401 |
| 485 delegate_manager_->DidPlay(delegate_id, true, true, false, | 402 delegate_manager_->DidPlay(delegate_id, true, true, false, |
| 486 MediaContentType::Persistent); | 403 MediaContentType::Persistent); |
| 487 CallOnMediaDelegatePlay(delegate_id); | 404 CallOnMediaDelegatePlay(delegate_id); |
| 488 EXPECT_NE(old_value, delegate_manager_->IsPlayingBackgroundVideo()); | 405 EXPECT_NE(old_value, delegate_manager_->IsPlayingBackgroundVideo()); |
| 489 } | 406 } |
| 490 | 407 |
| 491 #if defined(OS_ANDROID) | 408 #if defined(OS_ANDROID) |
| 492 | 409 |
| 493 TEST_F(RendererWebMediaPlayerDelegateTest, Histograms) { | 410 TEST_F(RendererWebMediaPlayerDelegateTest, Histograms) { |
| 494 testing::NiceMock<MockWebMediaPlayerDelegateObserver> observer; | 411 NiceMock<MockWebMediaPlayerDelegateObserver> observer; |
| 495 int delegate_id = delegate_manager_->AddObserver(&observer); | 412 int delegate_id = delegate_manager_->AddObserver(&observer); |
| 496 base::HistogramTester histogram_tester; | 413 base::HistogramTester histogram_tester; |
| 497 histogram_tester.ExpectTotalCount("Media.Android.BackgroundVideoTime", 0); | 414 histogram_tester.ExpectTotalCount("Media.Android.BackgroundVideoTime", 0); |
| 498 | 415 |
| 499 // Pausing or showing doesn't record anything as background playback | 416 // Pausing or showing doesn't record anything as background playback |
| 500 // hasn't started yet. | 417 // hasn't started yet. |
| 501 delegate_manager_->DidPlay(delegate_id, true, true, false, | 418 delegate_manager_->DidPlay(delegate_id, true, true, false, |
| 502 MediaContentType::Persistent); | 419 MediaContentType::Persistent); |
| 503 CallOnMediaDelegatePause(delegate_id); | 420 CallOnMediaDelegatePause(delegate_id); |
| 504 histogram_tester.ExpectTotalCount("Media.Android.BackgroundVideoTime", 0); | 421 histogram_tester.ExpectTotalCount("Media.Android.BackgroundVideoTime", 0); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 519 delegate_manager_->DidPlay(delegate_id, true, true, false, | 436 delegate_manager_->DidPlay(delegate_id, true, true, false, |
| 520 MediaContentType::Persistent); | 437 MediaContentType::Persistent); |
| 521 SetPlayingBackgroundVideo(true); | 438 SetPlayingBackgroundVideo(true); |
| 522 delegate_manager_->WasShown(); | 439 delegate_manager_->WasShown(); |
| 523 histogram_tester.ExpectTotalCount("Media.Android.BackgroundVideoTime", 2); | 440 histogram_tester.ExpectTotalCount("Media.Android.BackgroundVideoTime", 2); |
| 524 } | 441 } |
| 525 | 442 |
| 526 #endif // OS_ANDROID | 443 #endif // OS_ANDROID |
| 527 | 444 |
| 528 } // namespace media | 445 } // namespace media |
| OLD | NEW |