| OLD | NEW | 
| (Empty) |  | 
 |    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 | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #include "base/bind.h" | 
 |    6 #include "base/bind_helpers.h" | 
 |    7 #include "base/logging.h" | 
 |    8 #include "base/macros.h" | 
 |    9 #include "base/memory/ref_counted.h" | 
 |   10 #include "base/memory/scoped_ptr.h" | 
 |   11 #include "base/message_loop/message_loop.h" | 
 |   12 #include "base/time/time.h" | 
 |   13 #include "media/base/mock_filters.h" | 
 |   14 #include "media/base/pipeline.h" | 
 |   15 #include "media/filters/pipeline_controller.h" | 
 |   16 #include "testing/gmock/include/gmock/gmock.h" | 
 |   17 #include "testing/gtest/include/gtest/gtest.h" | 
 |   18  | 
 |   19 using ::testing::_; | 
 |   20 using ::testing::DoAll; | 
 |   21 using ::testing::Mock; | 
 |   22 using ::testing::Return; | 
 |   23 using ::testing::SaveArg; | 
 |   24 using ::testing::StrictMock; | 
 |   25  | 
 |   26 namespace media { | 
 |   27  | 
 |   28 class PipelineControllerTest : public ::testing::Test { | 
 |   29  public: | 
 |   30   PipelineControllerTest() | 
 |   31       : pipeline_controller_(&pipeline_, | 
 |   32                              base::Bind(&PipelineControllerTest::CreateRenderer, | 
 |   33                                         base::Unretained(this)), | 
 |   34                              base::Bind(&PipelineControllerTest::OnSeeked, | 
 |   35                                         base::Unretained(this)), | 
 |   36                              base::Bind(&PipelineControllerTest::OnSuspended, | 
 |   37                                         base::Unretained(this)), | 
 |   38                              base::Bind(&PipelineControllerTest::OnResumed, | 
 |   39                                         base::Unretained(this)), | 
 |   40                              base::Bind(&PipelineControllerTest::OnError, | 
 |   41                                         base::Unretained(this))) {} | 
 |   42  | 
 |   43   ~PipelineControllerTest() override {} | 
 |   44  | 
 |   45   PipelineStatusCB StartPipeline() { | 
 |   46     EXPECT_FALSE(pipeline_controller_.IsStable()); | 
 |   47     PipelineStatusCB start_cb; | 
 |   48     EXPECT_CALL(pipeline_, Start(_, _, _, _, _, _, _, _, _, _)) | 
 |   49         .WillOnce(SaveArg<4>(&start_cb)); | 
 |   50     pipeline_controller_.Start( | 
 |   51         nullptr, nullptr, false, base::Closure(), PipelineMetadataCB(), | 
 |   52         BufferingStateCB(), base::Closure(), AddTextTrackCB(), base::Closure()); | 
 |   53     Mock::VerifyAndClear(&pipeline_); | 
 |   54     EXPECT_FALSE(pipeline_controller_.IsStable()); | 
 |   55     return start_cb; | 
 |   56   } | 
 |   57  | 
 |   58   PipelineStatusCB SeekPipeline(base::TimeDelta time) { | 
 |   59     EXPECT_TRUE(pipeline_controller_.IsStable()); | 
 |   60     PipelineStatusCB seek_cb; | 
 |   61     EXPECT_CALL(pipeline_, Seek(time, _)).WillOnce(SaveArg<1>(&seek_cb)); | 
 |   62     pipeline_controller_.Seek(time, true); | 
 |   63     Mock::VerifyAndClear(&pipeline_); | 
 |   64     EXPECT_FALSE(pipeline_controller_.IsStable()); | 
 |   65     return seek_cb; | 
 |   66   } | 
 |   67  | 
 |   68   PipelineStatusCB SuspendPipeline() { | 
 |   69     EXPECT_TRUE(pipeline_controller_.IsStable()); | 
 |   70     PipelineStatusCB suspend_cb; | 
 |   71     EXPECT_CALL(pipeline_, Suspend(_)).WillOnce(SaveArg<0>(&suspend_cb)); | 
 |   72     pipeline_controller_.Suspend(); | 
 |   73     Mock::VerifyAndClear(&pipeline_); | 
 |   74     EXPECT_FALSE(pipeline_controller_.IsStable()); | 
 |   75     EXPECT_FALSE(pipeline_controller_.IsSuspended()); | 
 |   76     return suspend_cb; | 
 |   77   } | 
 |   78  | 
 |   79   PipelineStatusCB ResumePipeline() { | 
 |   80     EXPECT_TRUE(pipeline_controller_.IsSuspended()); | 
 |   81     PipelineStatusCB resume_cb; | 
 |   82     EXPECT_CALL(pipeline_, Resume(_, _, _)) | 
 |   83         .WillOnce( | 
 |   84             DoAll(SaveArg<1>(&last_resume_time_), SaveArg<2>(&resume_cb))); | 
 |   85     EXPECT_CALL(pipeline_, GetMediaTime()) | 
 |   86         .WillRepeatedly(Return(base::TimeDelta())); | 
 |   87     pipeline_controller_.Resume(); | 
 |   88     Mock::VerifyAndClear(&pipeline_); | 
 |   89     EXPECT_FALSE(pipeline_controller_.IsStable()); | 
 |   90     EXPECT_FALSE(pipeline_controller_.IsSuspended()); | 
 |   91     return resume_cb; | 
 |   92   } | 
 |   93  | 
 |   94   void Complete(const PipelineStatusCB& cb) { | 
 |   95     cb.Run(PIPELINE_OK); | 
 |   96     message_loop_.RunUntilIdle(); | 
 |   97   } | 
 |   98  | 
 |   99  protected: | 
 |  100   scoped_ptr<Renderer> CreateRenderer() { return scoped_ptr<Renderer>(); } | 
 |  101  | 
 |  102   void OnSeeked(bool time_updated) { | 
 |  103     was_seeked_ = true; | 
 |  104     last_seeked_time_updated_ = time_updated; | 
 |  105   } | 
 |  106  | 
 |  107   void OnSuspended() { was_suspended_ = true; } | 
 |  108  | 
 |  109   void OnResumed() { was_resumed_ = true; } | 
 |  110  | 
 |  111   void OnError(PipelineStatus status) { NOTREACHED(); } | 
 |  112  | 
 |  113   base::MessageLoop message_loop_; | 
 |  114  | 
 |  115   StrictMock<MockPipeline> pipeline_; | 
 |  116   PipelineController pipeline_controller_; | 
 |  117  | 
 |  118   bool was_seeked_ = false; | 
 |  119   bool last_seeked_time_updated_ = false; | 
 |  120   bool was_suspended_ = false; | 
 |  121   bool was_resumed_ = false; | 
 |  122   base::TimeDelta last_resume_time_; | 
 |  123  | 
 |  124   DISALLOW_COPY_AND_ASSIGN(PipelineControllerTest); | 
 |  125 }; | 
 |  126  | 
 |  127 TEST_F(PipelineControllerTest, Startup) { | 
 |  128   PipelineStatusCB start_cb = StartPipeline(); | 
 |  129   EXPECT_FALSE(was_seeked_); | 
 |  130  | 
 |  131   Complete(start_cb); | 
 |  132   EXPECT_TRUE(was_seeked_); | 
 |  133   EXPECT_FALSE(last_seeked_time_updated_); | 
 |  134   EXPECT_FALSE(was_suspended_); | 
 |  135   EXPECT_FALSE(was_resumed_); | 
 |  136   EXPECT_TRUE(pipeline_controller_.IsStable()); | 
 |  137 } | 
 |  138  | 
 |  139 TEST_F(PipelineControllerTest, SuspendResume) { | 
 |  140   Complete(StartPipeline()); | 
 |  141   EXPECT_TRUE(was_seeked_); | 
 |  142   was_seeked_ = false; | 
 |  143  | 
 |  144   Complete(SuspendPipeline()); | 
 |  145   EXPECT_TRUE(was_suspended_); | 
 |  146   EXPECT_FALSE(was_resumed_); | 
 |  147   EXPECT_FALSE(pipeline_controller_.IsStable()); | 
 |  148  | 
 |  149   Complete(ResumePipeline()); | 
 |  150   EXPECT_TRUE(was_resumed_); | 
 |  151   EXPECT_TRUE(pipeline_controller_.IsStable()); | 
 |  152  | 
 |  153   // |was_seeked_| should not be affected by Suspend()/Resume() at all. | 
 |  154   EXPECT_FALSE(was_seeked_); | 
 |  155 } | 
 |  156  | 
 |  157 TEST_F(PipelineControllerTest, PendingSuspend) { | 
 |  158   Complete(StartPipeline()); | 
 |  159  | 
 |  160   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 
 |  161   PipelineStatusCB seek_cb = SeekPipeline(seek_time); | 
 |  162   message_loop_.RunUntilIdle(); | 
 |  163  | 
 |  164   // While the seek is ongoing, request a suspend. | 
 |  165   // It will be a mock failure if pipeline_.Suspend() is called. | 
 |  166   pipeline_controller_.Suspend(); | 
 |  167   message_loop_.RunUntilIdle(); | 
 |  168  | 
 |  169   // Expect the suspend to trigger when the seek is completed. | 
 |  170   EXPECT_CALL(pipeline_, Suspend(_)); | 
 |  171   Complete(seek_cb); | 
 |  172 } | 
 |  173  | 
 |  174 TEST_F(PipelineControllerTest, SeekMergesWithResume) { | 
 |  175   Complete(StartPipeline()); | 
 |  176   Complete(SuspendPipeline()); | 
 |  177  | 
 |  178   // Request a seek while suspended. | 
 |  179   // It will be a mock failure if pipeline_.Seek() is called. | 
 |  180   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 
 |  181   pipeline_controller_.Seek(seek_time, true); | 
 |  182   message_loop_.RunUntilIdle(); | 
 |  183  | 
 |  184   // Resume and verify the resume time includes the seek. | 
 |  185   Complete(ResumePipeline()); | 
 |  186   EXPECT_EQ(seek_time, last_resume_time_); | 
 |  187   EXPECT_TRUE(last_seeked_time_updated_); | 
 |  188 } | 
 |  189  | 
 |  190 TEST_F(PipelineControllerTest, SeekMergesWithSeek) { | 
 |  191   Complete(StartPipeline()); | 
 |  192  | 
 |  193   base::TimeDelta seek_time_1 = base::TimeDelta::FromSeconds(5); | 
 |  194   PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time_1); | 
 |  195   message_loop_.RunUntilIdle(); | 
 |  196  | 
 |  197   // Request another seek while the first is ongoing. | 
 |  198   base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); | 
 |  199   pipeline_controller_.Seek(seek_time_2, true); | 
 |  200   message_loop_.RunUntilIdle(); | 
 |  201  | 
 |  202   // Request a third seek. (It should replace the second.) | 
 |  203   base::TimeDelta seek_time_3 = base::TimeDelta::FromSeconds(15); | 
 |  204   pipeline_controller_.Seek(seek_time_3, true); | 
 |  205   message_loop_.RunUntilIdle(); | 
 |  206  | 
 |  207   // Expect the third seek to trigger when the first seek completes. | 
 |  208   EXPECT_CALL(pipeline_, Seek(seek_time_3, _)); | 
 |  209   Complete(seek_cb_1); | 
 |  210 } | 
 |  211  | 
 |  212 }  // namespace media | 
| OLD | NEW |