// 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 <stdint.h>

#include "base/atomicops.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_checker.h"
#include "content/public/renderer/media_stream_audio_sink.h"
#include "content/renderer/media/media_stream_audio_source.h"
#include "content/renderer/media/media_stream_audio_track.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/web/WebHeap.h"

namespace content {

namespace {

constexpr int kSampleRate = 8000;
constexpr int kBufferSize = kSampleRate / 100;

// The maximum integer that can be exactly represented by the float data type.
constexpr int kMaxValueSafelyConvertableToFloat = 1 << 24;

// A simple MediaStreamAudioSource that spawns a real-time audio thread and
// emits audio samples with monotonically-increasing sample values. Includes
// hooks for the unit tests to confirm lifecycle status and to change audio
// format.
class FakeMediaStreamAudioSource
    : public MediaStreamAudioSource,
      public base::PlatformThread::Delegate {
 public:
  FakeMediaStreamAudioSource()
      : MediaStreamAudioSource(true),
        stop_event_(base::WaitableEvent::ResetPolicy::MANUAL,
                    base::WaitableEvent::InitialState::NOT_SIGNALED),
        next_buffer_size_(kBufferSize),
        sample_count_(0) {}

  ~FakeMediaStreamAudioSource() final {
    CHECK(main_thread_checker_.CalledOnValidThread());
    EnsureSourceIsStopped();
  }

  bool was_started() const {
    CHECK(main_thread_checker_.CalledOnValidThread());
    return !thread_.is_null();
  }

  bool was_stopped() const {
    CHECK(main_thread_checker_.CalledOnValidThread());
    return stop_event_.IsSignaled();
  }

  void SetBufferSize(int new_buffer_size) {
    CHECK(main_thread_checker_.CalledOnValidThread());
    base::subtle::NoBarrier_Store(&next_buffer_size_, new_buffer_size);
  }

 protected:
  bool EnsureSourceIsStarted() final {
    CHECK(main_thread_checker_.CalledOnValidThread());
    if (was_started())
      return true;
    if (was_stopped())
      return false;
    base::PlatformThread::CreateWithPriority(
        0, this, &thread_, base::ThreadPriority::REALTIME_AUDIO);
    return true;
  }

  void EnsureSourceIsStopped() final {
    CHECK(main_thread_checker_.CalledOnValidThread());
    if (was_stopped())
      return;
    stop_event_.Signal();
    if (was_started())
      base::PlatformThread::Join(thread_);
  }

  void ThreadMain() override {
    while (!stop_event_.IsSignaled()) {
      // If needed, notify of the new format and re-create |audio_bus_|.
      const int buffer_size = base::subtle::NoBarrier_Load(&next_buffer_size_);
      if (!audio_bus_ || audio_bus_->frames() != buffer_size) {
        MediaStreamAudioSource::SetFormat(media::AudioParameters(
            media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
            media::CHANNEL_LAYOUT_MONO, kSampleRate, 16, buffer_size));
        audio_bus_ = media::AudioBus::Create(1, buffer_size);
      }

      // Deliver the next chunk of audio data. Each sample value is its offset
      // from the very first sample.
      float* const data = audio_bus_->channel(0);
      for (int i = 0; i < buffer_size; ++i)
        data[i] = ++sample_count_;
      CHECK_LT(sample_count_, kMaxValueSafelyConvertableToFloat);
      MediaStreamAudioSource::DeliverDataToTracks(*audio_bus_,
                                                  base::TimeTicks::Now());

      // Sleep before producing the next chunk of audio.
      base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(
          base::Time::kMicrosecondsPerSecond * buffer_size / kSampleRate));
    }
  }

 private:
  base::ThreadChecker main_thread_checker_;

  base::PlatformThreadHandle thread_;
  mutable base::WaitableEvent stop_event_;

  base::subtle::Atomic32 next_buffer_size_;
  std::unique_ptr<media::AudioBus> audio_bus_;
  int sample_count_;

  DISALLOW_COPY_AND_ASSIGN(FakeMediaStreamAudioSource);
};

// A simple MediaStreamAudioSink that consumes audio and confirms the sample
// values. Includes hooks for the unit tests to monitor the format and flow of
// audio, whether the audio is silent, and the propagation of the "enabled"
// state.
class FakeMediaStreamAudioSink : public MediaStreamAudioSink {
 public:
  enum EnableState {
    NO_ENABLE_NOTIFICATION,
    WAS_ENABLED,
    WAS_DISABLED
  };

  FakeMediaStreamAudioSink()
      : MediaStreamAudioSink(), expected_sample_count_(-1),
        num_on_data_calls_(0), audio_is_silent_(true), was_ended_(false),
        enable_state_(NO_ENABLE_NOTIFICATION) {}

  ~FakeMediaStreamAudioSink() final {
    CHECK(main_thread_checker_.CalledOnValidThread());
  }

  media::AudioParameters params() const {
    CHECK(main_thread_checker_.CalledOnValidThread());
    base::AutoLock auto_lock(params_lock_);
    return params_;
  }

  int num_on_data_calls() const {
    CHECK(main_thread_checker_.CalledOnValidThread());
    return base::subtle::NoBarrier_Load(&num_on_data_calls_);
  }

  bool is_audio_silent() const {
    CHECK(main_thread_checker_.CalledOnValidThread());
    return !!base::subtle::NoBarrier_Load(&audio_is_silent_);
  }

  bool was_ended() const {
    CHECK(main_thread_checker_.CalledOnValidThread());
    return was_ended_;
  }

  EnableState enable_state() const {
    CHECK(main_thread_checker_.CalledOnValidThread());
    return enable_state_;
  }

  void OnSetFormat(const media::AudioParameters& params) final {
    ASSERT_TRUE(params.IsValid());
    base::AutoLock auto_lock(params_lock_);
    params_ = params;
  }

  void OnData(const media::AudioBus& audio_bus,
              base::TimeTicks estimated_capture_time) final {
    ASSERT_TRUE(params_.IsValid());
    ASSERT_FALSE(was_ended_);

    ASSERT_EQ(params_.channels(), audio_bus.channels());
    ASSERT_EQ(params_.frames_per_buffer(), audio_bus.frames());
    if (audio_bus.AreFramesZero()) {
      base::subtle::NoBarrier_Store(&audio_is_silent_, 1);
      expected_sample_count_ = -1;  // Reset for when audio comes back.
    } else {
      base::subtle::NoBarrier_Store(&audio_is_silent_, 0);
      const float* const data = audio_bus.channel(0);
      if (expected_sample_count_ == -1)
        expected_sample_count_ = static_cast<int64_t>(data[0]);
      CHECK_LE(expected_sample_count_ + audio_bus.frames(),
               kMaxValueSafelyConvertableToFloat);
      for (int i = 0; i < audio_bus.frames(); ++i) {
        const float expected_sample_value = expected_sample_count_;
        ASSERT_EQ(expected_sample_value, data[i]);
        ++expected_sample_count_;
      }
    }

    ASSERT_TRUE(!estimated_capture_time.is_null());
    ASSERT_LT(last_estimated_capture_time_, estimated_capture_time);
    last_estimated_capture_time_ = estimated_capture_time;

    base::subtle::NoBarrier_AtomicIncrement(&num_on_data_calls_, 1);
  }

  void OnReadyStateChanged(
      blink::WebMediaStreamSource::ReadyState state) final {
    CHECK(main_thread_checker_.CalledOnValidThread());
    if (state == blink::WebMediaStreamSource::ReadyStateEnded)
      was_ended_ = true;
  }

  void OnEnabledChanged(bool enabled) final {
    CHECK(main_thread_checker_.CalledOnValidThread());
    enable_state_ = enabled ? WAS_ENABLED : WAS_DISABLED;
  }

 private:
  base::ThreadChecker main_thread_checker_;

  mutable base::Lock params_lock_;
  media::AudioParameters params_;
  int expected_sample_count_;
  base::TimeTicks last_estimated_capture_time_;
  base::subtle::Atomic32 num_on_data_calls_;
  base::subtle::Atomic32 audio_is_silent_;
  bool was_ended_;
  EnableState enable_state_;

  DISALLOW_COPY_AND_ASSIGN(FakeMediaStreamAudioSink);
};

}  // namespace

class MediaStreamAudioTest : public ::testing::Test {
 protected:
  void SetUp() override {
    blink_audio_source_.initialize(blink::WebString::fromUTF8("audio_id"),
                                   blink::WebMediaStreamSource::TypeAudio,
                                   blink::WebString::fromUTF8("audio_track"),
                                   false /* remote */);
    blink_audio_track_.initialize(blink_audio_source_.id(),
                                  blink_audio_source_);
  }

  void TearDown() override {
    blink_audio_track_.reset();
    blink_audio_source_.reset();
    blink::WebHeap::collectAllGarbageForTesting();
  }

  FakeMediaStreamAudioSource* source() const {
    return static_cast<FakeMediaStreamAudioSource*>(
        MediaStreamAudioSource::From(blink_audio_source_));
  }

  MediaStreamAudioTrack* track() const {
    return MediaStreamAudioTrack::From(blink_audio_track_);
  }

  blink::WebMediaStreamSource blink_audio_source_;
  blink::WebMediaStreamTrack blink_audio_track_;

  base::MessageLoop message_loop_;
};

// Tests that a simple source-->track-->sink connection and audio data flow
// works.
TEST_F(MediaStreamAudioTest, BasicUsage) {
  // Create the source, but it should not be started yet.
  ASSERT_FALSE(source());
  blink_audio_source_.setExtraData(new FakeMediaStreamAudioSource());
  ASSERT_TRUE(source());
  EXPECT_FALSE(source()->was_started());
  EXPECT_FALSE(source()->was_stopped());

  // Connect a track to the source. This should auto-start the source.
  ASSERT_FALSE(track());
  EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
  ASSERT_TRUE(track());
  EXPECT_TRUE(source()->was_started());
  EXPECT_FALSE(source()->was_stopped());

  // Connect a sink to the track. This should begin audio flow to the
  // sink. Wait and confirm that three OnData() calls were made from the audio
  // thread.
  FakeMediaStreamAudioSink sink;
  EXPECT_FALSE(sink.was_ended());
  track()->AddSink(&sink);
  const int start_count = sink.num_on_data_calls();
  while (sink.num_on_data_calls() - start_count < 3)
    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());

  // Check that the audio parameters propagated to the track and sink.
  const media::AudioParameters expected_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
      kSampleRate, 16, kBufferSize);
  EXPECT_TRUE(expected_params.Equals(track()->GetOutputFormat()));
  EXPECT_TRUE(expected_params.Equals(sink.params()));

  // Stop the track. Since this was the last track connected to the source, the
  // source should automatically stop. In addition, the sink should receive a
  // ReadyStateEnded notification.
  track()->Stop();
  EXPECT_TRUE(source()->was_started());
  EXPECT_TRUE(source()->was_stopped());
  EXPECT_TRUE(sink.was_ended());

  track()->RemoveSink(&sink);
}

// Tests that "ended" tracks can be connected after the source has stopped.
TEST_F(MediaStreamAudioTest, ConnectTrackAfterSourceStopped) {
  // Create the source, connect one track, and stop it. This should
  // automatically stop the source.
  blink_audio_source_.setExtraData(new FakeMediaStreamAudioSource());
  ASSERT_TRUE(source());
  EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
  track()->Stop();
  EXPECT_TRUE(source()->was_started());
  EXPECT_TRUE(source()->was_stopped());

  // Now, connect another track. ConnectToTrack() will return false, but there
  // should be a MediaStreamAudioTrack instance created and owned by the
  // blink::WebMediaStreamTrack.
  blink::WebMediaStreamTrack another_blink_track;
  another_blink_track.initialize(blink_audio_source_.id(), blink_audio_source_);
  EXPECT_FALSE(MediaStreamAudioTrack::From(another_blink_track));
  EXPECT_FALSE(source()->ConnectToTrack(another_blink_track));
  EXPECT_TRUE(MediaStreamAudioTrack::From(another_blink_track));
}

// Tests that a sink is immediately "ended" when connected to a stopped track.
TEST_F(MediaStreamAudioTest, AddSinkToStoppedTrack) {
  // Create a track and stop it. Then, when adding a sink, the sink should get
  // the ReadyStateEnded notification immediately.
  MediaStreamAudioTrack track(true);
  track.Stop();
  FakeMediaStreamAudioSink sink;
  EXPECT_FALSE(sink.was_ended());
  track.AddSink(&sink);
  EXPECT_TRUE(sink.was_ended());
  EXPECT_EQ(0, sink.num_on_data_calls());
  track.RemoveSink(&sink);
}

// Tests that audio format changes at the source propagate to the track and
// sink.
TEST_F(MediaStreamAudioTest, FormatChangesPropagate) {
  // Create a source, connect it to track, and connect the track to a
  // sink.
  blink_audio_source_.setExtraData(new FakeMediaStreamAudioSource());
  ASSERT_TRUE(source());
  EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
  ASSERT_TRUE(track());
  FakeMediaStreamAudioSink sink;
  ASSERT_TRUE(!sink.params().IsValid());
  track()->AddSink(&sink);

  // Wait until valid parameters are propagated to the sink, and then confirm
  // the parameters are correct at the track and the sink.
  while (!sink.params().IsValid())
    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
  const media::AudioParameters expected_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
      kSampleRate, 16, kBufferSize);
  EXPECT_TRUE(expected_params.Equals(track()->GetOutputFormat()));
  EXPECT_TRUE(expected_params.Equals(sink.params()));

  // Now, trigger a format change by doubling the buffer size.
  source()->SetBufferSize(kBufferSize * 2);

  // Wait until the new buffer size propagates to the sink.
  while (sink.params().frames_per_buffer() == kBufferSize)
    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
  EXPECT_EQ(kBufferSize * 2, track()->GetOutputFormat().frames_per_buffer());
  EXPECT_EQ(kBufferSize * 2, sink.params().frames_per_buffer());

  track()->RemoveSink(&sink);
}

// Tests that tracks deliver audio when enabled and silent audio when
// disabled. Whenever a track is enabled or disabled, the sink's
// OnEnabledChanged() method should be called.
TEST_F(MediaStreamAudioTest, EnableAndDisableTracks) {
  // Create a source and connect it to track.
  blink_audio_source_.setExtraData(new FakeMediaStreamAudioSource());
  ASSERT_TRUE(source());
  EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
  ASSERT_TRUE(track());

  // Connect the track to a sink and expect the sink to be notified that the
  // track is enabled.
  FakeMediaStreamAudioSink sink;
  EXPECT_TRUE(sink.is_audio_silent());
  EXPECT_EQ(FakeMediaStreamAudioSink::NO_ENABLE_NOTIFICATION,
            sink.enable_state());
  track()->AddSink(&sink);
  EXPECT_EQ(FakeMediaStreamAudioSink::WAS_ENABLED, sink.enable_state());

  // Wait until non-silent audio reaches the sink.
  while (sink.is_audio_silent())
    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());

  // Now, disable the track and expect the sink to be notified.
  track()->SetEnabled(false);
  EXPECT_EQ(FakeMediaStreamAudioSink::WAS_DISABLED, sink.enable_state());

  // Wait until silent audio reaches the sink.
  while (!sink.is_audio_silent())
    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());

  // Create a second track and a second sink, but this time the track starts out
  // disabled. Expect the sink to be notified at the start that the track is
  // disabled.
  blink::WebMediaStreamTrack another_blink_track;
  another_blink_track.initialize(blink_audio_source_.id(), blink_audio_source_);
  EXPECT_TRUE(source()->ConnectToTrack(another_blink_track));
  MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(false);
  FakeMediaStreamAudioSink another_sink;
  MediaStreamAudioTrack::From(another_blink_track)->AddSink(&another_sink);
  EXPECT_EQ(FakeMediaStreamAudioSink::WAS_DISABLED,
            another_sink.enable_state());

  // Wait until OnData() is called on the second sink. Expect the audio to be
  // silent.
  const int start_count = another_sink.num_on_data_calls();
  while (another_sink.num_on_data_calls() == start_count)
    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
  EXPECT_TRUE(another_sink.is_audio_silent());

  // Now, enable the second track and expect the second sink to be notified.
  MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(true);
  EXPECT_EQ(FakeMediaStreamAudioSink::WAS_ENABLED, another_sink.enable_state());

  // Wait until non-silent audio reaches the second sink.
  while (another_sink.is_audio_silent())
    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());

  // The first track and sink should not have been affected by changing the
  // enabled state of the second track and sink. They should still be disabled,
  // with silent audio being consumed at the sink.
  EXPECT_EQ(FakeMediaStreamAudioSink::WAS_DISABLED, sink.enable_state());
  EXPECT_TRUE(sink.is_audio_silent());

  MediaStreamAudioTrack::From(another_blink_track)->RemoveSink(&another_sink);
  track()->RemoveSink(&sink);
}

}  // namespace content
