| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2012 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 <list> |    5 #include <list> | 
|    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/message_loop.h" |    9 #include "base/message_loop.h" | 
|   10 #include "base/rand_util.h" |   10 #include "base/rand_util.h" | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   90   } |   90   } | 
|   91  |   91  | 
|   92  private: |   92  private: | 
|   93   base::WaitableEvent data_pulled_; |   93   base::WaitableEvent data_pulled_; | 
|   94  |   94  | 
|   95   DISALLOW_COPY_AND_ASSIGN(TestAudioSource); |   95   DISALLOW_COPY_AND_ASSIGN(TestAudioSource); | 
|   96 }; |   96 }; | 
|   97  |   97  | 
|   98 }  // namespace |   98 }  // namespace | 
|   99  |   99  | 
|  100 class VirtualAudioInputStreamTest : public testing::Test { |  100 class VirtualAudioInputStreamTest : public testing::TestWithParam<bool> { | 
|  101  public: |  101  public: | 
|  102   VirtualAudioInputStreamTest() |  102   VirtualAudioInputStreamTest() | 
|  103       : audio_thread_(new base::Thread("AudioThread")), |  103       : audio_thread_(new base::Thread("AudioThread")), | 
 |  104         worker_thread_(new base::Thread("AudioWorkerThread")), | 
|  104         stream_(NULL), |  105         stream_(NULL), | 
|  105         closed_stream_(false, false) { |  106         closed_stream_(false, false) { | 
|  106     audio_thread_->Start(); |  107     audio_thread_->Start(); | 
|  107     audio_message_loop_ = audio_thread_->message_loop_proxy(); |  108     audio_message_loop_ = audio_thread_->message_loop_proxy(); | 
|  108   } |  109   } | 
|  109  |  110  | 
|  110   virtual ~VirtualAudioInputStreamTest() { |  111   virtual ~VirtualAudioInputStreamTest() { | 
|  111     SyncWithAudioThread(); |  112     SyncWithAudioThread(); | 
|  112  |  113  | 
|  113     DCHECK(output_streams_.empty()); |  114     DCHECK(output_streams_.empty()); | 
|  114     DCHECK(stopped_output_streams_.empty()); |  115     DCHECK(stopped_output_streams_.empty()); | 
|  115   } |  116   } | 
|  116  |  117  | 
|  117   void Create() { |  118   void Create() { | 
 |  119     const bool worker_is_separate_thread = GetParam(); | 
|  118     stream_ = new VirtualAudioInputStream( |  120     stream_ = new VirtualAudioInputStream( | 
|  119         kParams, audio_message_loop_, |  121         kParams, GetWorkerLoop(worker_is_separate_thread), | 
|  120         base::Bind(&base::DeletePointer<VirtualAudioInputStream>)); |  122         base::Bind(&base::DeletePointer<VirtualAudioInputStream>)); | 
|  121     stream_->Open(); |  123     stream_->Open(); | 
|  122   } |  124   } | 
|  123  |  125  | 
|  124   void Start() { |  126   void Start() { | 
|  125     EXPECT_CALL(input_callback_, OnClose(_)); |  127     EXPECT_CALL(input_callback_, OnClose(_)); | 
|  126     EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _)) |  128     EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _)) | 
|  127         .Times(AtLeast(1)); |  129         .Times(AtLeast(1)); | 
|  128  |  130  | 
|  129     ASSERT_TRUE(!!stream_); |  131     ASSERT_TRUE(!!stream_); | 
|  130     stream_->Start(&input_callback_); |  132     stream_->Start(&input_callback_); | 
|  131   } |  133   } | 
|  132  |  134  | 
|  133   void CreateAndStartOneOutputStream() { |  135   void CreateAndStartOneOutputStream() { | 
|  134     ASSERT_TRUE(!!stream_); |  136     ASSERT_TRUE(!!stream_); | 
|  135     AudioOutputStream* const output_stream = new VirtualAudioOutputStream( |  137     AudioOutputStream* const output_stream = new VirtualAudioOutputStream( | 
|  136         kParams, |  138         kParams, | 
|  137         audio_message_loop_.get(), |  | 
|  138         stream_, |  139         stream_, | 
|  139         base::Bind(&base::DeletePointer<VirtualAudioOutputStream>)); |  140         base::Bind(&base::DeletePointer<VirtualAudioOutputStream>)); | 
|  140     output_streams_.push_back(output_stream); |  141     output_streams_.push_back(output_stream); | 
|  141  |  142  | 
|  142     output_stream->Open(); |  143     output_stream->Open(); | 
|  143     output_stream->Start(&source_); |  144     output_stream->Start(&source_); | 
|  144   } |  145   } | 
|  145  |  146  | 
|  146   void Stop() { |  147   void Stop() { | 
|  147     ASSERT_TRUE(!!stream_); |  148     ASSERT_TRUE(!!stream_); | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  205       (*it)->Start(&source_); |  206       (*it)->Start(&source_); | 
|  206       output_streams_.push_back(*it); |  207       output_streams_.push_back(*it); | 
|  207     } |  208     } | 
|  208     stopped_output_streams_.clear(); |  209     stopped_output_streams_.clear(); | 
|  209   } |  210   } | 
|  210  |  211  | 
|  211   const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const { |  212   const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const { | 
|  212     return audio_message_loop_; |  213     return audio_message_loop_; | 
|  213   } |  214   } | 
|  214  |  215  | 
 |  216   const scoped_refptr<base::MessageLoopProxy>& GetWorkerLoop( | 
 |  217       bool worker_is_separate_thread) { | 
 |  218     if (worker_is_separate_thread) { | 
 |  219       if (!worker_thread_->IsRunning()) { | 
 |  220         worker_thread_->Start(); | 
 |  221         worker_message_loop_ = worker_thread_->message_loop_proxy(); | 
 |  222       } | 
 |  223       return worker_message_loop_; | 
 |  224     } else { | 
 |  225       return audio_message_loop_; | 
 |  226     } | 
 |  227   } | 
 |  228  | 
|  215  private: |  229  private: | 
|  216   void SyncWithAudioThread() { |  230   void SyncWithAudioThread() { | 
|  217     base::WaitableEvent done(false, false); |  231     base::WaitableEvent done(false, false); | 
|  218     audio_message_loop_->PostTask( |  232     audio_message_loop_->PostTask( | 
|  219         FROM_HERE, |  233         FROM_HERE, | 
|  220         base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); |  234         base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); | 
|  221     done.Wait(); |  235     done.Wait(); | 
|  222   } |  236   } | 
|  223  |  237  | 
|  224   scoped_ptr<base::Thread> audio_thread_; |  238   scoped_ptr<base::Thread> audio_thread_; | 
|  225   scoped_refptr<base::MessageLoopProxy> audio_message_loop_; |  239   scoped_refptr<base::MessageLoopProxy> audio_message_loop_; | 
 |  240   scoped_ptr<base::Thread> worker_thread_; | 
 |  241   scoped_refptr<base::MessageLoopProxy> worker_message_loop_; | 
|  226  |  242  | 
|  227   VirtualAudioInputStream* stream_; |  243   VirtualAudioInputStream* stream_; | 
|  228   MockInputCallback input_callback_; |  244   MockInputCallback input_callback_; | 
|  229   base::WaitableEvent closed_stream_; |  245   base::WaitableEvent closed_stream_; | 
|  230  |  246  | 
|  231   std::list<AudioOutputStream*> output_streams_; |  247   std::list<AudioOutputStream*> output_streams_; | 
|  232   std::list<AudioOutputStream*> stopped_output_streams_; |  248   std::list<AudioOutputStream*> stopped_output_streams_; | 
|  233   TestAudioSource source_; |  249   TestAudioSource source_; | 
|  234  |  250  | 
|  235   DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest); |  251   DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest); | 
|  236 }; |  252 }; | 
|  237  |  253  | 
|  238 #define RUN_ON_AUDIO_THREAD(method)  \ |  254 #define RUN_ON_AUDIO_THREAD(method)  \ | 
|  239   audio_message_loop()->PostTask(  \ |  255   audio_message_loop()->PostTask(  \ | 
|  240       FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::method,  \ |  256       FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::method,  \ | 
|  241                             base::Unretained(this))) |  257                             base::Unretained(this))) | 
|  242  |  258  | 
|  243 TEST_F(VirtualAudioInputStreamTest, CreateAndClose) { |  259 TEST_P(VirtualAudioInputStreamTest, CreateAndClose) { | 
|  244   RUN_ON_AUDIO_THREAD(Create); |  260   RUN_ON_AUDIO_THREAD(Create); | 
|  245   RUN_ON_AUDIO_THREAD(Close); |  261   RUN_ON_AUDIO_THREAD(Close); | 
|  246   WaitUntilClosed(); |  262   WaitUntilClosed(); | 
|  247 } |  263 } | 
|  248  |  264  | 
|  249 TEST_F(VirtualAudioInputStreamTest, NoOutputs) { |  265 TEST_P(VirtualAudioInputStreamTest, NoOutputs) { | 
|  250   RUN_ON_AUDIO_THREAD(Create); |  266   RUN_ON_AUDIO_THREAD(Create); | 
|  251   RUN_ON_AUDIO_THREAD(Start); |  267   RUN_ON_AUDIO_THREAD(Start); | 
|  252   WaitForDataToFlow(); |  268   WaitForDataToFlow(); | 
|  253   RUN_ON_AUDIO_THREAD(Stop); |  269   RUN_ON_AUDIO_THREAD(Stop); | 
|  254   RUN_ON_AUDIO_THREAD(Close); |  270   RUN_ON_AUDIO_THREAD(Close); | 
|  255   WaitUntilClosed(); |  271   WaitUntilClosed(); | 
|  256 } |  272 } | 
|  257  |  273  | 
|  258 TEST_F(VirtualAudioInputStreamTest, SingleOutput) { |  274 TEST_P(VirtualAudioInputStreamTest, SingleOutput) { | 
|  259   RUN_ON_AUDIO_THREAD(Create); |  275   RUN_ON_AUDIO_THREAD(Create); | 
|  260   RUN_ON_AUDIO_THREAD(Start); |  276   RUN_ON_AUDIO_THREAD(Start); | 
|  261   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |  277   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 
|  262   WaitForDataToFlow(); |  278   WaitForDataToFlow(); | 
|  263   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |  279   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 
|  264   RUN_ON_AUDIO_THREAD(Stop); |  280   RUN_ON_AUDIO_THREAD(Stop); | 
|  265   RUN_ON_AUDIO_THREAD(Close); |  281   RUN_ON_AUDIO_THREAD(Close); | 
|  266   WaitUntilClosed(); |  282   WaitUntilClosed(); | 
|  267 } |  283 } | 
|  268  |  284  | 
|  269 TEST_F(VirtualAudioInputStreamTest, SingleOutputPausedAndRestarted) { |  285 TEST_P(VirtualAudioInputStreamTest, SingleOutputPausedAndRestarted) { | 
|  270   RUN_ON_AUDIO_THREAD(Create); |  286   RUN_ON_AUDIO_THREAD(Create); | 
|  271   RUN_ON_AUDIO_THREAD(Start); |  287   RUN_ON_AUDIO_THREAD(Start); | 
|  272   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |  288   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 
|  273   WaitForDataToFlow(); |  289   WaitForDataToFlow(); | 
|  274   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |  290   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 
|  275   RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); |  291   RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); | 
|  276   WaitForDataToFlow(); |  292   WaitForDataToFlow(); | 
|  277   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |  293   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 
|  278   RUN_ON_AUDIO_THREAD(Stop); |  294   RUN_ON_AUDIO_THREAD(Stop); | 
|  279   RUN_ON_AUDIO_THREAD(Close); |  295   RUN_ON_AUDIO_THREAD(Close); | 
|  280   WaitUntilClosed(); |  296   WaitUntilClosed(); | 
|  281 } |  297 } | 
|  282  |  298  | 
|  283 TEST_F(VirtualAudioInputStreamTest, MultipleOutputs) { |  299 TEST_P(VirtualAudioInputStreamTest, MultipleOutputs) { | 
|  284   RUN_ON_AUDIO_THREAD(Create); |  300   RUN_ON_AUDIO_THREAD(Create); | 
|  285   RUN_ON_AUDIO_THREAD(Start); |  301   RUN_ON_AUDIO_THREAD(Start); | 
|  286   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |  302   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 
|  287   WaitForDataToFlow(); |  303   WaitForDataToFlow(); | 
|  288   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |  304   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 
|  289   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |  305   RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 
|  290   WaitForDataToFlow(); |  306   WaitForDataToFlow(); | 
|  291   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |  307   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 
|  292   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |  308   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 
|  293   WaitForDataToFlow(); |  309   WaitForDataToFlow(); | 
|  294   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |  310   RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 
|  295   RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); |  311   RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); | 
|  296   WaitForDataToFlow(); |  312   WaitForDataToFlow(); | 
|  297   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |  313   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 
|  298   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |  314   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 
|  299   RUN_ON_AUDIO_THREAD(Stop); |  315   RUN_ON_AUDIO_THREAD(Stop); | 
|  300   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |  316   RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 
|  301   RUN_ON_AUDIO_THREAD(Close); |  317   RUN_ON_AUDIO_THREAD(Close); | 
|  302   WaitUntilClosed(); |  318   WaitUntilClosed(); | 
|  303 } |  319 } | 
|  304  |  320  | 
|  305 // A combination of all of the above tests with many output streams. |  321 // A combination of all of the above tests with many output streams. | 
|  306 TEST_F(VirtualAudioInputStreamTest, ComprehensiveTest) { |  322 TEST_P(VirtualAudioInputStreamTest, ComprehensiveTest) { | 
|  307   static const int kNumOutputs = 8; |  323   static const int kNumOutputs = 8; | 
|  308   static const int kHalfNumOutputs = kNumOutputs / 2; |  324   static const int kHalfNumOutputs = kNumOutputs / 2; | 
|  309   static const int kPauseIterations = 5; |  325   static const int kPauseIterations = 5; | 
|  310  |  326  | 
|  311   RUN_ON_AUDIO_THREAD(Create); |  327   RUN_ON_AUDIO_THREAD(Create); | 
|  312   for (int i = 0; i < kHalfNumOutputs; ++i) { |  328   for (int i = 0; i < kHalfNumOutputs; ++i) { | 
|  313     RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |  329     RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 
|  314   } |  330   } | 
|  315   RUN_ON_AUDIO_THREAD(Start); |  331   RUN_ON_AUDIO_THREAD(Start); | 
|  316   WaitForDataToFlow(); |  332   WaitForDataToFlow(); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  328     RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |  344     RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 
|  329   } |  345   } | 
|  330   RUN_ON_AUDIO_THREAD(Stop); |  346   RUN_ON_AUDIO_THREAD(Stop); | 
|  331   for (int i = 0; i < kHalfNumOutputs; ++i) { |  347   for (int i = 0; i < kHalfNumOutputs; ++i) { | 
|  332     RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |  348     RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 
|  333   } |  349   } | 
|  334   RUN_ON_AUDIO_THREAD(Close); |  350   RUN_ON_AUDIO_THREAD(Close); | 
|  335   WaitUntilClosed(); |  351   WaitUntilClosed(); | 
|  336 } |  352 } | 
|  337  |  353  | 
 |  354 INSTANTIATE_TEST_CASE_P(SingleVersusMultithreaded, | 
 |  355                         VirtualAudioInputStreamTest, | 
 |  356                         ::testing::Values(false, true)); | 
 |  357  | 
|  338 }  // namespace media |  358 }  // namespace media | 
| OLD | NEW |