| // Copyright 2016 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "remoting/protocol/audio_decode_scheduler.h" | 
 |  | 
 | #include <utility> | 
 |  | 
 | #include "base/functional/bind.h" | 
 | #include "base/functional/callback_helpers.h" | 
 | #include "base/run_loop.h" | 
 | #include "base/test/task_environment.h" | 
 | #include "base/threading/thread.h" | 
 | #include "remoting/base/auto_thread.h" | 
 | #include "remoting/base/auto_thread_task_runner.h" | 
 | #include "remoting/proto/audio.pb.h" | 
 | #include "remoting/protocol/session_config.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 |  | 
 | namespace remoting::protocol { | 
 |  | 
 | namespace { | 
 |  | 
 | const int kAudioSampleBytes = 4; | 
 | const uint8_t kDummyAudioData = 0x8B; | 
 |  | 
 | class FakeAudioConsumer : public AudioStub { | 
 |  public: | 
 |   FakeAudioConsumer() {} | 
 |  | 
 |   FakeAudioConsumer(const FakeAudioConsumer&) = delete; | 
 |   FakeAudioConsumer& operator=(const FakeAudioConsumer&) = delete; | 
 |  | 
 |   ~FakeAudioConsumer() override = default; | 
 |  | 
 |   base::WeakPtr<FakeAudioConsumer> GetWeakPtr() { | 
 |     return weak_factory_.GetWeakPtr(); | 
 |   } | 
 |  | 
 |   // AudioStub implementation. | 
 |   void ProcessAudioPacket(std::unique_ptr<AudioPacket> packet, | 
 |                           base::OnceClosure done) override { | 
 |     if (!done.is_null()) { | 
 |       std::move(done).Run(); | 
 |     } | 
 |   } | 
 |  | 
 |  private: | 
 |   base::WeakPtrFactory<FakeAudioConsumer> weak_factory_{this}; | 
 | }; | 
 |  | 
 | }  // namespace | 
 |  | 
 | class AudioDecodeSchedulerTest : public ::testing::Test { | 
 |  public: | 
 |   AudioDecodeSchedulerTest() = default; | 
 |  | 
 |   void SetUp() override; | 
 |   void TearDown() override; | 
 |  | 
 |  protected: | 
 |   base::test::SingleThreadTaskEnvironment task_environment_; | 
 |   base::RunLoop run_loop_; | 
 |   scoped_refptr<AutoThreadTaskRunner> audio_decode_task_runner_; | 
 |   scoped_refptr<AutoThreadTaskRunner> main_task_runner_; | 
 |   std::unique_ptr<SessionConfig> session_config_; | 
 | }; | 
 |  | 
 | void AudioDecodeSchedulerTest::SetUp() { | 
 |   main_task_runner_ = new AutoThreadTaskRunner( | 
 |       task_environment_.GetMainThreadTaskRunner(), run_loop_.QuitClosure()); | 
 |   audio_decode_task_runner_ = AutoThread::Create("decode", main_task_runner_); | 
 |   session_config_ = SessionConfig::ForTestWithAudio(); | 
 | } | 
 |  | 
 | void AudioDecodeSchedulerTest::TearDown() { | 
 |   // Release the task runners, so that the test can quit. | 
 |   audio_decode_task_runner_ = nullptr; | 
 |   main_task_runner_ = nullptr; | 
 |  | 
 |   // Run the MessageLoop until everything has torn down. | 
 |   run_loop_.Run(); | 
 | } | 
 |  | 
 | // TODO(nicholss): Could share the following in a common class for use | 
 | // in other places. | 
 | std::unique_ptr<AudioPacket> CreatePacketWithSamplingRate_( | 
 |     AudioPacket::SamplingRate rate, | 
 |     int samples) { | 
 |   std::unique_ptr<AudioPacket> packet(new AudioPacket()); | 
 |   packet->set_encoding(AudioPacket::ENCODING_RAW); | 
 |   packet->set_sampling_rate(rate); | 
 |   packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2); | 
 |   packet->set_channels(AudioPacket::CHANNELS_STEREO); | 
 |  | 
 |   // The data must be a multiple of 4 bytes (channels x bytes_per_sample). | 
 |   std::string data; | 
 |   data.resize(samples * kAudioSampleBytes, kDummyAudioData); | 
 |   packet->add_data(data); | 
 |  | 
 |   return packet; | 
 | } | 
 |  | 
 | std::unique_ptr<AudioPacket> CreatePacket44100Hz_(int samples) { | 
 |   return CreatePacketWithSamplingRate_(AudioPacket::SAMPLING_RATE_44100, | 
 |                                        samples); | 
 | } | 
 |  | 
 | std::unique_ptr<AudioPacket> CreatePacket48000Hz_(int samples) { | 
 |   return CreatePacketWithSamplingRate_(AudioPacket::SAMPLING_RATE_48000, | 
 |                                        samples); | 
 | } | 
 |  | 
 | TEST_F(AudioDecodeSchedulerTest, Shutdown) { | 
 |   std::unique_ptr<FakeAudioConsumer> audio_consumer(new FakeAudioConsumer()); | 
 |   std::unique_ptr<AudioDecodeScheduler> audio_scheduler( | 
 |       new AudioDecodeScheduler(audio_decode_task_runner_, | 
 |                                audio_consumer->GetWeakPtr())); | 
 |  | 
 |   audio_scheduler->Initialize(*session_config_); | 
 |  | 
 |   audio_scheduler->ProcessAudioPacket(CreatePacket44100Hz_(1000), | 
 |                                       base::DoNothing()); | 
 |  | 
 |   audio_scheduler.reset(); | 
 |   audio_consumer.reset(); | 
 |   // TODO(nicholss): This test does not really test anything. Add a way to get a | 
 |   // count of the calls to AddAudioPacket. | 
 | } | 
 |  | 
 | }  // namespace remoting::protocol |