// 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 "media/base/silent_sink_suspender.h"

#include "base/run_loop.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/test_message_loop.h"
#include "media/base/fake_audio_render_callback.h"
#include "media/base/mock_audio_renderer_sink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::test::RunClosure;

namespace media {

class SilentSinkSuspenderTest : public testing::Test {
 public:
  SilentSinkSuspenderTest()
      : params_(AudioParameters::AUDIO_FAKE, CHANNEL_LAYOUT_MONO, 44100, 128),
        mock_sink_(new testing::StrictMock<MockAudioRendererSink>()),
        fake_callback_(0.1, params_.sample_rate()),
        temp_bus_(AudioBus::Create(params_)),
        // Set a negative timeout so any silence will suspend immediately.
        suspender_(&fake_callback_,
                   base::Seconds(-1),
                   params_,
                   mock_sink_,
                   test_loop_.task_runner()) {}

  SilentSinkSuspenderTest(const SilentSinkSuspenderTest&) = delete;
  SilentSinkSuspenderTest& operator=(const SilentSinkSuspenderTest&) = delete;

  ~SilentSinkSuspenderTest() override = default;

 protected:
  base::TestMessageLoop test_loop_;
  const AudioParameters params_;
  scoped_refptr<testing::StrictMock<MockAudioRendererSink>> mock_sink_;
  FakeAudioRenderCallback fake_callback_;
  std::unique_ptr<AudioBus> temp_bus_;
  SilentSinkSuspender suspender_;
};

TEST_F(SilentSinkSuspenderTest, BasicPassthough) {
  temp_bus_->Zero();
  auto delay = base::Milliseconds(20);
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(delay, base::TimeTicks(), 0, temp_bus_.get()));

  // Delay should remain.
  EXPECT_EQ(delay, fake_callback_.last_delay());
  EXPECT_FALSE(temp_bus_->AreFramesZero());
}

TEST_F(SilentSinkSuspenderTest, SuspendResumeTriggered) {
  // Verify a normal Render() doesn't invoke suspend.
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_FALSE(temp_bus_->AreFramesZero());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());

  // Mute all audio generated by the callback, this should suspend immediately.
  fake_callback_.set_volume(0);
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_TRUE(temp_bus_->AreFramesZero());
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_sink_, Pause())
        .WillOnce(RunClosure(run_loop.QuitClosure()));
    run_loop.Run();
    EXPECT_TRUE(suspender_.IsUsingFakeSinkForTesting());
  }

  // Unmute the audio, the FakeWorker inside |suspender_| should be running now,
  // so we don't need to manually invoke Render().
  fake_callback_.reset();
  fake_callback_.set_volume(1);
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_sink_, Play())
        .WillOnce(RunClosure(run_loop.QuitClosure()));
    run_loop.Run();
    EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());
  }

  // The first Render() after resume should return the first buffer which was
  // not silent.
  fake_callback_.reset();
  std::unique_ptr<AudioBus> true_bus = AudioBus::Create(params_);
  fake_callback_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                        true_bus.get());
  EXPECT_FALSE(true_bus->AreFramesZero());
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_EQ(memcmp(temp_bus_->channel(0), true_bus->channel(0),
                   temp_bus_->frames() * sizeof(float)),
            0);
}

TEST_F(SilentSinkSuspenderTest, MultipleSuspend) {
  // Mute all audio generated by the callback, this should suspend immediately.
  fake_callback_.set_volume(0);
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_TRUE(temp_bus_->AreFramesZero());

  // A second render should only result in a single Pause() call.
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));

  EXPECT_CALL(*mock_sink_, Pause());
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(suspender_.IsUsingFakeSinkForTesting());
}

TEST_F(SilentSinkSuspenderTest, MultipleResume) {
  // Mute all audio generated by the callback, this should suspend immediately.
  fake_callback_.set_volume(0);
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_TRUE(temp_bus_->AreFramesZero());
  EXPECT_CALL(*mock_sink_, Pause());
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(suspender_.IsUsingFakeSinkForTesting());

  // Unmute the data.
  fake_callback_.set_volume(1);

  // Prepare our equality testers.
  fake_callback_.reset();
  std::unique_ptr<AudioBus> true_bus1 = AudioBus::Create(params_);
  fake_callback_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                        true_bus1.get());
  std::unique_ptr<AudioBus> true_bus2 = AudioBus::Create(params_);
  fake_callback_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                        true_bus2.get());
  EXPECT_NE(memcmp(true_bus1->channel(0), true_bus2->channel(0),
                   true_bus1->frames() * sizeof(float)),
            0);

  // Reset the fake callback data generation and force two Render() calls before
  // the sink can transition.
  fake_callback_.reset();
  EXPECT_EQ(
      temp_bus_->frames(),
      suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0, nullptr));
  EXPECT_EQ(
      temp_bus_->frames(),
      suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0, nullptr));
  EXPECT_CALL(*mock_sink_, Play());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());

  // Each render after resuming should return one of the non-silent bus.
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_EQ(memcmp(temp_bus_->channel(0), true_bus1->channel(0),
                   temp_bus_->frames() * sizeof(float)),
            0);
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_EQ(memcmp(temp_bus_->channel(0), true_bus2->channel(0),
                   temp_bus_->frames() * sizeof(float)),
            0);
}

TEST_F(SilentSinkSuspenderTest, SetDetectSilence) {
  // Verify a normal Render() doesn't invoke suspend.
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_FALSE(temp_bus_->AreFramesZero());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());

  // Mute all audio generated by the callback, this should suspend immediately.
  fake_callback_.set_volume(0);
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_TRUE(temp_bus_->AreFramesZero());
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_sink_, Pause())
        .WillOnce(RunClosure(run_loop.QuitClosure()));
    run_loop.Run();
    EXPECT_TRUE(suspender_.IsUsingFakeSinkForTesting());
  }

  // Disable silence detection, but don't unmute the audio, the FakeWorker
  // inside |suspender_| should be running now, so we don't need to manually
  // invoke Render().
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_sink_, Play())
        .WillOnce(RunClosure(run_loop.QuitClosure()));

    // Disable silence detection which should put us back on the real sink.
    suspender_.SetDetectSilence(false);

    run_loop.Run();
    EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());
  }

  // Run one more Render() to ensure we stay on the real sink even w/ silent
  // audio.
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));

  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());

  // Enable silence detection which should transition to the fake sink on the
  // next Render().
  suspender_.SetDetectSilence(true);
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_TRUE(temp_bus_->AreFramesZero());
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_sink_, Pause())
        .WillOnce(RunClosure(run_loop.QuitClosure()));
    run_loop.Run();
    EXPECT_TRUE(suspender_.IsUsingFakeSinkForTesting());
  }
}

TEST_F(SilentSinkSuspenderTest, OnPaused) {
  // Verify a normal Render() doesn't invoke suspend.
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_FALSE(temp_bus_->AreFramesZero());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());

  // OnPaused() at this point should do nothing, since we're on the real sink.
  suspender_.OnPaused();

  // Mute all audio generated by the callback, this should suspend immediately.
  fake_callback_.set_volume(0);
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));
  EXPECT_TRUE(temp_bus_->AreFramesZero());
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_sink_, Pause())
        .WillOnce(RunClosure(run_loop.QuitClosure()));
    run_loop.Run();
    EXPECT_TRUE(suspender_.IsUsingFakeSinkForTesting());
  }

  // Call OnPaused(), which should disable the fake sink, but won't call Play().
  suspender_.OnPaused();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());

  // Render silence again, which should attempt to transition to the fake sink.
  temp_bus_->Zero();
  EXPECT_EQ(temp_bus_->frames(),
            suspender_.Render(base::TimeDelta(), base::TimeTicks(), 0,
                              temp_bus_.get()));

  // OnPaused() should cancel any pending transitions.
  suspender_.OnPaused();

  // We should not transition to the fake sink now.
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(suspender_.IsUsingFakeSinkForTesting());
}

}  // namespace media
