/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "call/adaptation/video_stream_adapter.h"

#include <string>
#include <utility>

#include "absl/types/optional.h"
#include "api/scoped_refptr.h"
#include "api/video/video_adaptation_reason.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_config.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/encoder_settings.h"
#include "call/adaptation/test/fake_frame_rate_provider.h"
#include "call/adaptation/test/fake_resource.h"
#include "call/adaptation/test/fake_video_stream_input_state_provider.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"
#include "rtc_base/string_encode.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"
#include "test/testsupport/rtc_expect_death.h"

namespace webrtc {

using ::testing::_;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SaveArg;

namespace {

const int kBalancedHighResolutionPixels = 1280 * 720;
const int kBalancedHighFrameRateFps = 30;

const int kBalancedMediumResolutionPixels = 640 * 480;
const int kBalancedMediumFrameRateFps = 20;

const int kBalancedLowResolutionPixels = 320 * 240;
const int kBalancedLowFrameRateFps = 10;

std::string BalancedFieldTrialConfig() {
  return "WebRTC-Video-BalancedDegradationSettings/pixels:" +
         rtc::ToString(kBalancedLowResolutionPixels) + "|" +
         rtc::ToString(kBalancedMediumResolutionPixels) + "|" +
         rtc::ToString(kBalancedHighResolutionPixels) +
         ",fps:" + rtc::ToString(kBalancedLowFrameRateFps) + "|" +
         rtc::ToString(kBalancedMediumFrameRateFps) + "|" +
         rtc::ToString(kBalancedHighFrameRateFps) + "/";
}

// Responsible for adjusting the inputs to VideoStreamAdapter (SetInput), such
// as pixels and frame rate, according to the most recent source restrictions.
// This helps tests that apply adaptations multiple times: if the input is not
// adjusted between adaptations, the subsequent adaptations fail with
// kAwaitingPreviousAdaptation.
class FakeVideoStream {
 public:
  FakeVideoStream(VideoStreamAdapter* adapter,
                  FakeVideoStreamInputStateProvider* provider,
                  int input_pixels,
                  int input_fps,
                  int min_pixels_per_frame)
      : adapter_(adapter),
        provider_(provider),
        input_pixels_(input_pixels),
        input_fps_(input_fps),
        min_pixels_per_frame_(min_pixels_per_frame) {
    provider_->SetInputState(input_pixels_, input_fps_, min_pixels_per_frame_);
  }

  int input_pixels() const { return input_pixels_; }
  int input_fps() const { return input_fps_; }

  // Performs ApplyAdaptation() followed by SetInput() with input pixels and
  // frame rate adjusted according to the resulting restrictions.
  void ApplyAdaptation(Adaptation adaptation) {
    adapter_->ApplyAdaptation(adaptation, nullptr);
    // Update input pixels and fps according to the resulting restrictions.
    auto restrictions = adapter_->source_restrictions();
    if (restrictions.target_pixels_per_frame().has_value()) {
      RTC_DCHECK(!restrictions.max_pixels_per_frame().has_value() ||
                 restrictions.max_pixels_per_frame().value() >=
                     restrictions.target_pixels_per_frame().value());
      input_pixels_ = restrictions.target_pixels_per_frame().value();
    } else if (restrictions.max_pixels_per_frame().has_value()) {
      input_pixels_ = restrictions.max_pixels_per_frame().value();
    }
    if (restrictions.max_frame_rate().has_value()) {
      input_fps_ = restrictions.max_frame_rate().value();
    }
    provider_->SetInputState(input_pixels_, input_fps_, min_pixels_per_frame_);
  }

 private:
  VideoStreamAdapter* adapter_;
  FakeVideoStreamInputStateProvider* provider_;
  int input_pixels_;
  int input_fps_;
  int min_pixels_per_frame_;
};

class FakeVideoStreamAdapterListner : public VideoSourceRestrictionsListener {
 public:
  void OnVideoSourceRestrictionsUpdated(
      VideoSourceRestrictions restrictions,
      const VideoAdaptationCounters& adaptation_counters,
      rtc::scoped_refptr<Resource> reason,
      const VideoSourceRestrictions& unfiltered_restrictions) override {
    calls_++;
    last_restrictions_ = unfiltered_restrictions;
  }

  int calls() const { return calls_; }

  VideoSourceRestrictions last_restrictions() const {
    return last_restrictions_;
  }

 private:
  int calls_ = 0;
  VideoSourceRestrictions last_restrictions_;
};

class MockAdaptationConstraint : public AdaptationConstraint {
 public:
  MOCK_METHOD(bool,
              IsAdaptationUpAllowed,
              (const VideoStreamInputState& input_state,
               const VideoSourceRestrictions& restrictions_before,
               const VideoSourceRestrictions& restrictions_after),
              (const, override));

  // MOCK_METHOD(std::string, Name, (), (const, override));
  std::string Name() const override { return "MockAdaptationConstraint"; }
};

}  // namespace

class VideoStreamAdapterTest : public ::testing::Test {
 public:
  VideoStreamAdapterTest()
      : field_trials_(BalancedFieldTrialConfig()),
        resource_(FakeResource::Create("FakeResource")),
        adapter_(&input_state_provider_,
                 &encoder_stats_observer_,
                 field_trials_) {}

 protected:
  webrtc::test::ScopedKeyValueConfig field_trials_;
  FakeVideoStreamInputStateProvider input_state_provider_;
  rtc::scoped_refptr<Resource> resource_;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter_;
};

TEST_F(VideoStreamAdapterTest, NoRestrictionsByDefault) {
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest, MaintainFramerate_DecreasesPixelsToThreeFifths) {
  const int kInputPixels = 1280 * 720;
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(kInputPixels, 30,
                                      kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  adapter_.ApplyAdaptation(adaptation, nullptr);
  EXPECT_EQ(static_cast<size_t>((kInputPixels * 3) / 5),
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(absl::nullopt, adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_DecreasesPixelsToLimitReached) {
  const int kMinPixelsPerFrame = 640 * 480;

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(kMinPixelsPerFrame + 1, 30,
                                      kMinPixelsPerFrame);
  EXPECT_CALL(encoder_stats_observer_, OnMinPixelLimitReached());
  // Even though we are above kMinPixelsPerFrame, because adapting down would
  // have exceeded the limit, we are said to have reached the limit already.
  // This differs from the frame rate adaptation logic, which would have clamped
  // to the limit in the first step and reported kLimitReached in the second
  // step.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kLimitReached, adaptation.status());
}

TEST_F(VideoStreamAdapterTest, MaintainFramerate_IncreasePixelsToFiveThirds) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Go down twice, ensuring going back up is still a restricted resolution.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
  int input_pixels = fake_stream.input_pixels();
  // Go up once. The target is 5/3 and the max is 12/5 of the target.
  const int target = (input_pixels * 5) / 3;
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(static_cast<size_t>((target * 12) / 5),
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(static_cast<size_t>(target),
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(absl::nullopt, adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest, MaintainFramerate_IncreasePixelsToUnrestricted) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // We are unrestricted by default and should not be able to adapt up.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationUp().status());
  // If we go down once and then back up we should not have any restrictions.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_DecreasesFpsToTwoThirds) {
  const int kInputFps = 30;

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  input_state_provider_.SetInputState(1280 * 720, kInputFps,
                                      kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  adapter_.ApplyAdaptation(adaptation, nullptr);
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>((kInputFps * 2) / 3),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_DecreasesFpsToLimitReached) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720,
                              kMinFrameRateFps + 1, kDefaultMinPixelsPerFrame);
  // If we are not yet at the limit and the next step would exceed it, the step
  // is clamped such that we end up exactly on the limit.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);
  EXPECT_EQ(static_cast<double>(kMinFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // Having reached the limit, the next adaptation down is not valid.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationDown().status());
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_IncreaseFpsToThreeHalves) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Go down twice, ensuring going back up is still a restricted frame rate.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(2, adapter_.adaptation_counters().fps_adaptations);
  int input_fps = fake_stream.input_fps();
  // Go up once. The target is 3/2 of the input.
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>((input_fps * 3) / 2),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_IncreaseFpsToUnrestricted) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // We are unrestricted by default and should not be able to adapt up.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationUp().status());
  // If we go down once and then back up we should not have any restrictions.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest, Balanced_DecreaseFrameRate) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(kBalancedMediumResolutionPixels,
                                      kBalancedHighFrameRateFps,
                                      kDefaultMinPixelsPerFrame);
  // If our frame rate is higher than the frame rate associated with our
  // resolution we should try to adapt to the frame rate associated with our
  // resolution: kBalancedMediumFrameRateFps.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  adapter_.ApplyAdaptation(adaptation, nullptr);
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedMediumFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest, Balanced_DecreaseResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  FakeVideoStream fake_stream(
      &adapter_, &input_state_provider_, kBalancedHighResolutionPixels,
      kBalancedHighFrameRateFps, kDefaultMinPixelsPerFrame);
  // If we are not below the current resolution's frame rate limit, we should
  // adapt resolution according to "maintain-framerate" logic (three fifths).
  //
  // However, since we are unlimited at the start and input frame rate is not
  // below kBalancedHighFrameRateFps, we first restrict the frame rate to
  // kBalancedHighFrameRateFps even though that is our current frame rate. This
  // does prevent the source from going higher, though, so it's technically not
  // a NO-OP.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
  }
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // Verify "maintain-framerate" logic the second time we adapt: Frame rate
  // restrictions remains the same and resolution goes down.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
  }
  constexpr size_t kReducedPixelsFirstStep =
      static_cast<size_t>((kBalancedHighResolutionPixels * 3) / 5);
  EXPECT_EQ(kReducedPixelsFirstStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // If we adapt again, because the balanced settings' proposed frame rate is
  // still kBalancedHighFrameRateFps, "maintain-framerate" will trigger again.
  static_assert(kReducedPixelsFirstStep > kBalancedMediumResolutionPixels,
                "The reduced resolution is still greater than the next lower "
                "balanced setting resolution");
  constexpr size_t kReducedPixelsSecondStep = (kReducedPixelsFirstStep * 3) / 5;
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
  }
  EXPECT_EQ(kReducedPixelsSecondStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(absl::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

// Testing when to adapt frame rate and when to adapt resolution is quite
// entangled, so this test covers both cases.
//
// There is an asymmetry: When we adapt down we do it in one order, but when we
// adapt up we don't do it in the reverse order. Instead we always try to adapt
// frame rate first according to balanced settings' configs and only when the
// frame rate is already achieved do we adjust the resolution.
TEST_F(VideoStreamAdapterTest, Balanced_IncreaseFrameRateAndResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  FakeVideoStream fake_stream(
      &adapter_, &input_state_provider_, kBalancedHighResolutionPixels,
      kBalancedHighFrameRateFps, kDefaultMinPixelsPerFrame);
  // The desired starting point of this test is having adapted frame rate twice.
  // This requires performing a number of adaptations.
  constexpr size_t kReducedPixelsFirstStep =
      static_cast<size_t>((kBalancedHighResolutionPixels * 3) / 5);
  constexpr size_t kReducedPixelsSecondStep = (kReducedPixelsFirstStep * 3) / 5;
  constexpr size_t kReducedPixelsThirdStep = (kReducedPixelsSecondStep * 3) / 5;
  static_assert(kReducedPixelsFirstStep > kBalancedMediumResolutionPixels,
                "The first pixel reduction is greater than the balanced "
                "settings' medium pixel configuration");
  static_assert(kReducedPixelsSecondStep > kBalancedMediumResolutionPixels,
                "The second pixel reduction is greater than the balanced "
                "settings' medium pixel configuration");
  static_assert(kReducedPixelsThirdStep <= kBalancedMediumResolutionPixels,
                "The third pixel reduction is NOT greater than the balanced "
                "settings' medium pixel configuration");
  // The first adaptation should affect the frame rate: See
  // Balanced_DecreaseResolution for explanation why.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  // The next three adaptations affects the resolution, because we have to reach
  // kBalancedMediumResolutionPixels before a lower frame rate is considered by
  // BalancedDegradationSettings. The number three is derived from the
  // static_asserts above.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(kReducedPixelsFirstStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(kReducedPixelsSecondStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(kReducedPixelsThirdStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  // Thus, the next adaptation will reduce frame rate to
  // kBalancedMediumFrameRateFps.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(static_cast<double>(kBalancedMediumFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(3, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(2, adapter_.adaptation_counters().fps_adaptations);
  // Adapt up!
  // While our resolution is in the medium-range, the frame rate associated with
  // the next resolution configuration up ("high") is kBalancedHighFrameRateFps
  // and "balanced" prefers adapting frame rate if not already applied.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
              adapter_.source_restrictions().max_frame_rate());
    EXPECT_EQ(3, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  }
  // Now that we have already achieved the next frame rate up, we act according
  // to "maintain-framerate". We go back up in resolution. Due to rounding
  // errors we don't end up back at kReducedPixelsSecondStep. Rather we get to
  // kReducedPixelsSecondStepUp, which is off by one compared to
  // kReducedPixelsSecondStep.
  constexpr size_t kReducedPixelsSecondStepUp =
      (kReducedPixelsThirdStep * 5) / 3;
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(kReducedPixelsSecondStepUp,
              adapter_.source_restrictions().target_pixels_per_frame());
    EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  }
  // Now that our resolution is back in the high-range, the next frame rate to
  // try out is "unlimited".
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(absl::nullopt, adapter_.source_restrictions().max_frame_rate());
    EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);
  }
  // Now only adapting resolution remains.
  constexpr size_t kReducedPixelsFirstStepUp =
      (kReducedPixelsSecondStepUp * 5) / 3;
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(kReducedPixelsFirstStepUp,
              adapter_.source_restrictions().target_pixels_per_frame());
    EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);
  }
  // The last step up should make us entirely unrestricted.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
    EXPECT_EQ(0, adapter_.adaptation_counters().Total());
  }
}

TEST_F(VideoStreamAdapterTest, Balanced_LimitReached) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  FakeVideoStream fake_stream(
      &adapter_, &input_state_provider_, kBalancedLowResolutionPixels,
      kBalancedLowFrameRateFps, kDefaultMinPixelsPerFrame);
  // Attempting to adapt up while unrestricted should result in kLimitReached.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationUp().status());
  // Adapting down once result in restricted frame rate, in this case we reach
  // the lowest possible frame rate immediately: kBalancedLowFrameRateFps.
  EXPECT_CALL(encoder_stats_observer_, OnMinPixelLimitReached()).Times(2);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(static_cast<double>(kBalancedLowFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // Any further adaptation must follow "maintain-framerate" rules (these are
  // covered in more depth by the MaintainFramerate tests). This test does not
  // assert exactly how resolution is adjusted, only that resolution always
  // decreases and that we eventually reach kLimitReached.
  size_t previous_resolution = kBalancedLowResolutionPixels;
  bool did_reach_limit = false;
  // If we have not reached the limit within 5 adaptations something is wrong...
  for (int i = 0; i < 5; i++) {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    if (adaptation.status() == Adaptation::Status::kLimitReached) {
      did_reach_limit = true;
      break;
    }
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_LT(adapter_.source_restrictions().max_pixels_per_frame().value(),
              previous_resolution);
    previous_resolution =
        adapter_.source_restrictions().max_pixels_per_frame().value();
  }
  EXPECT_TRUE(did_reach_limit);
  // Frame rate restrictions are the same as before.
  EXPECT_EQ(static_cast<double>(kBalancedLowFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

// kAwaitingPreviousAdaptation is only supported in "maintain-framerate".
TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_AwaitingPreviousAdaptationDown) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  // Adapt down once, but don't update the input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  {
    // Having performed the adaptation, but not updated the input based on the
    // new restrictions, adapting again in the same direction will not work.
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
              adaptation.status());
  }
}

// kAwaitingPreviousAdaptation is only supported in "maintain-framerate".
TEST_F(VideoStreamAdapterTest, MaintainFramerate_AwaitingPreviousAdaptationUp) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Perform two adaptation down so that adapting up twice is possible.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
  // Adapt up once, but don't update the input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationUp(), nullptr);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  {
    // Having performed the adaptation, but not updated the input based on the
    // new restrictions, adapting again in the same direction will not work.
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
              adaptation.status());
  }
}

TEST_F(VideoStreamAdapterTest,
       MaintainResolution_AdaptsUpAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down in fps for later.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);

  // We should be able to adapt in framerate one last time after the change of
  // degradation preference.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_AdaptsUpAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down in resolution for later.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);

  // We should be able to adapt in framerate one last time after the change of
  // degradation preference.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       PendingResolutionIncreaseAllowsAdaptUpAfterSwitchToMaintainResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt fps down so we can adapt up later in the test.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  // Apply adaptation up but don't update input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationUp(), nullptr);
  EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
            adapter_.GetAdaptationUp().status());

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
}

TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_AdaptsDownAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once, should change FPS.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  // Adaptation down should apply after the degradation prefs change.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       MaintainResolution_AdaptsDownAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once, should change FPS.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);

  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(
    VideoStreamAdapterTest,
    PendingResolutionDecreaseAllowsAdaptDownAfterSwitchToMaintainResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Apply adaptation but don't update the input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
            adapter_.GetAdaptationDown().status());
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
}

TEST_F(VideoStreamAdapterTest, RestrictionBroadcasted) {
  FakeVideoStreamAdapterListner listener;
  adapter_.AddRestrictionsListener(&listener);
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Not broadcast on invalid ApplyAdaptation.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    adapter_.ApplyAdaptation(adaptation, nullptr);
    EXPECT_EQ(0, listener.calls());
  }

  // Broadcast on ApplyAdaptation.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(1, listener.calls());
    EXPECT_EQ(adaptation.restrictions(), listener.last_restrictions());
  }

  // Broadcast on ClearRestrictions().
  adapter_.ClearRestrictions();
  EXPECT_EQ(2, listener.calls());
  EXPECT_EQ(VideoSourceRestrictions(), listener.last_restrictions());
}

TEST_F(VideoStreamAdapterTest, AdaptationHasNextRestrcitions) {
  // Any non-disabled DegradationPreference will do.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // When adaptation is not possible.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kLimitReached, adaptation.status());
    EXPECT_EQ(adaptation.restrictions(), adapter_.source_restrictions());
    EXPECT_EQ(0, adaptation.counters().Total());
  }
  // When we adapt down.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(adaptation.restrictions(), adapter_.source_restrictions());
    EXPECT_EQ(adaptation.counters(), adapter_.adaptation_counters());
  }
  // When we adapt up.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(adaptation.restrictions(), adapter_.source_restrictions());
    EXPECT_EQ(adaptation.counters(), adapter_.adaptation_counters());
  }
}

TEST_F(VideoStreamAdapterTest,
       SetDegradationPreferenceToOrFromBalancedClearsRestrictions) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_NE(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_NE(0, adapter_.adaptation_counters().Total());
  // Changing from non-balanced to balanced clears the restrictions.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
  // Apply adaptation again.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_NE(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_NE(0, adapter_.adaptation_counters().Total());
  // Changing from balanced to non-balanced clears the restrictions.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionAdaptsResolutionInMaintainFramerate) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(1, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(0, adaptation.counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionReturnsWithStatusInDisabledAndMaintainResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::DISABLED);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptDownResolution().status());
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptDownResolution().status());
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionAdaptsFpsAndResolutionInBalanced) {
  // Note: This test depends on BALANCED implementation, but with current
  // implementation and input state settings, BALANCED will adapt resolution and
  // frame rate once.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(1, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(1, adaptation.counters().fps_adaptations);
}

TEST_F(
    VideoStreamAdapterTest,
    GetAdaptDownResolutionAdaptsOnlyResolutionIfFpsAlreadyAdapterInBalanced) {
  // Note: This test depends on BALANCED implementation, but with current
  // implementation and input state settings, BALANCED will adapt resolution
  // only.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(1280 * 720, 5, kDefaultMinPixelsPerFrame);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);

  auto first_adaptation = adapter_.GetAdaptationDown();
  fake_stream.ApplyAdaptation(first_adaptation);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(1, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(first_adaptation.counters().fps_adaptations,
            adaptation.counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionAdaptsOnlyFpsIfResolutionLowInBalanced) {
  // Note: This test depends on BALANCED implementation, but with current
  // implementation and input state settings, BALANCED will adapt resolution
  // only.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(kDefaultMinPixelsPerFrame, 30,
                                      kDefaultMinPixelsPerFrame);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(0, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(1, adaptation.counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       AdaptationDisabledStatusAlwaysWhenDegradationPreferenceDisabled) {
  adapter_.SetDegradationPreference(DegradationPreference::DISABLED);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptationDown().status());
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptationUp().status());
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptDownResolution().status());
}

TEST_F(VideoStreamAdapterTest, AdaptationConstraintAllowsAdaptationsUp) {
  testing::StrictMock<MockAdaptationConstraint> adaptation_constraint;
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  adapter_.AddAdaptationConstraint(&adaptation_constraint);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once so we can adapt up later.
  auto first_adaptation = adapter_.GetAdaptationDown();
  fake_stream.ApplyAdaptation(first_adaptation);

  EXPECT_CALL(adaptation_constraint,
              IsAdaptationUpAllowed(_, first_adaptation.restrictions(), _))
      .WillOnce(Return(true));
  EXPECT_EQ(Adaptation::Status::kValid, adapter_.GetAdaptationUp().status());
  adapter_.RemoveAdaptationConstraint(&adaptation_constraint);
}

TEST_F(VideoStreamAdapterTest, AdaptationConstraintDisallowsAdaptationsUp) {
  testing::StrictMock<MockAdaptationConstraint> adaptation_constraint;
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  adapter_.AddAdaptationConstraint(&adaptation_constraint);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once so we can adapt up later.
  auto first_adaptation = adapter_.GetAdaptationDown();
  fake_stream.ApplyAdaptation(first_adaptation);

  EXPECT_CALL(adaptation_constraint,
              IsAdaptationUpAllowed(_, first_adaptation.restrictions(), _))
      .WillOnce(Return(false));
  EXPECT_EQ(Adaptation::Status::kRejectedByConstraint,
            adapter_.GetAdaptationUp().status());
  adapter_.RemoveAdaptationConstraint(&adaptation_constraint);
}

// Death tests.
// Disabled on Android because death tests misbehave on Android, see
// base/test/gtest_util.h.
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

TEST(VideoStreamAdapterDeathTest,
     SetDegradationPreferenceInvalidatesAdaptations) {
  webrtc::test::ScopedKeyValueConfig field_trials;
  FakeVideoStreamInputStateProvider input_state_provider;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_,
                             field_trials);
  adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider.SetInputState(1280 * 720, 30, kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter.GetAdaptationDown();
  adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  EXPECT_DEATH(adapter.ApplyAdaptation(adaptation, nullptr), "");
}

TEST(VideoStreamAdapterDeathTest, AdaptDownInvalidatesAdaptations) {
  webrtc::test::ScopedKeyValueConfig field_trials;
  FakeVideoStreamInputStateProvider input_state_provider;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_,
                             field_trials);
  adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  input_state_provider.SetInputState(1280 * 720, 30, kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter.GetAdaptationDown();
  adapter.GetAdaptationDown();
  EXPECT_DEATH(adapter.ApplyAdaptation(adaptation, nullptr), "");
}

#endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

}  // namespace webrtc
