/*
 *  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/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.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_) {}

 protected:
  webrtc::test::ScopedFieldTrials 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) {
  FakeVideoStreamInputStateProvider input_state_provider;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_);
  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) {
  FakeVideoStreamInputStateProvider input_state_provider;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_);
  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
