[Adaptation] Move IsAdaptationUpAllowed/OnAdaptationApplied out of API.

IsAdaptationUpAllowed is moved from Resource to AdaptationConstraint.
OnAdaptationApplied is moved from Resource to AdaptationListener.

In a future CL, Resource will be moved to api/, but
AdaptationConstraint and AdaptationListener will stay in call/.

The processor, encode stream and manager are updated to keep track of
both resources, constraints and listeners. Fakes and tests are updated.
After this CL, the manager's inner classes that prevent adaptation
implement AdaptationConstraint instead of Resource.

Bug: webrtc:11525
Change-Id: Ie9cd5b1ba7d8e161951e131ab8f6bd9d5cf765bf
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176368
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@google.com>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31409}
diff --git a/call/adaptation/BUILD.gn b/call/adaptation/BUILD.gn
index 291911a..b5c72ef 100644
--- a/call/adaptation/BUILD.gn
+++ b/call/adaptation/BUILD.gn
@@ -10,6 +10,10 @@
 
 rtc_library("resource_adaptation") {
   sources = [
+    "adaptation_constraint.cc",
+    "adaptation_constraint.h",
+    "adaptation_listener.cc",
+    "adaptation_listener.h",
     "encoder_settings.cc",
     "encoder_settings.h",
     "resource.cc",
@@ -80,6 +84,10 @@
     testonly = true
 
     sources = [
+      "test/fake_adaptation_constraint.cc",
+      "test/fake_adaptation_constraint.h",
+      "test/fake_adaptation_listener.cc",
+      "test/fake_adaptation_listener.h",
       "test/fake_frame_rate_provider.cc",
       "test/fake_frame_rate_provider.h",
       "test/fake_resource.cc",
diff --git a/call/adaptation/adaptation_constraint.cc b/call/adaptation/adaptation_constraint.cc
new file mode 100644
index 0000000..d62bb74
--- /dev/null
+++ b/call/adaptation/adaptation_constraint.cc
@@ -0,0 +1,17 @@
+/*
+ *  Copyright 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/adaptation_constraint.h"
+
+namespace webrtc {
+
+AdaptationConstraint::~AdaptationConstraint() {}
+
+}  // namespace webrtc
diff --git a/call/adaptation/adaptation_constraint.h b/call/adaptation/adaptation_constraint.h
new file mode 100644
index 0000000..ce15e32
--- /dev/null
+++ b/call/adaptation/adaptation_constraint.h
@@ -0,0 +1,43 @@
+/*
+ *  Copyright 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.
+ */
+
+#ifndef CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
+#define CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
+
+#include <string>
+
+#include "api/scoped_refptr.h"
+#include "call/adaptation/resource.h"
+#include "call/adaptation/video_source_restrictions.h"
+#include "call/adaptation/video_stream_input_state.h"
+
+namespace webrtc {
+
+// Adaptation constraints have the ability to prevent applying a proposed
+// adaptation (expressed as restrictions before/after adaptation).
+class AdaptationConstraint {
+ public:
+  virtual ~AdaptationConstraint();
+
+  virtual std::string Name() const = 0;
+
+  // TODO(https://crbug.com/webrtc/11172): When we have multi-stream adaptation
+  // support, this interface needs to indicate which stream the adaptation
+  // applies to.
+  virtual bool IsAdaptationUpAllowed(
+      const VideoStreamInputState& input_state,
+      const VideoSourceRestrictions& restrictions_before,
+      const VideoSourceRestrictions& restrictions_after,
+      rtc::scoped_refptr<Resource> reason_resource) const = 0;
+};
+
+}  // namespace webrtc
+
+#endif  // CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
diff --git a/call/adaptation/adaptation_listener.cc b/call/adaptation/adaptation_listener.cc
new file mode 100644
index 0000000..acc1564
--- /dev/null
+++ b/call/adaptation/adaptation_listener.cc
@@ -0,0 +1,17 @@
+/*
+ *  Copyright 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/adaptation_listener.h"
+
+namespace webrtc {
+
+AdaptationListener::~AdaptationListener() {}
+
+}  // namespace webrtc
diff --git a/call/adaptation/adaptation_listener.h b/call/adaptation/adaptation_listener.h
new file mode 100644
index 0000000..028897e
--- /dev/null
+++ b/call/adaptation/adaptation_listener.h
@@ -0,0 +1,41 @@
+/*
+ *  Copyright 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.
+ */
+
+#ifndef CALL_ADAPTATION_ADAPTATION_LISTENER_H_
+#define CALL_ADAPTATION_ADAPTATION_LISTENER_H_
+
+#include "api/scoped_refptr.h"
+#include "call/adaptation/resource.h"
+#include "call/adaptation/video_source_restrictions.h"
+#include "call/adaptation/video_stream_input_state.h"
+
+namespace webrtc {
+
+// TODO(hbos): Can this be consolidated with
+// ResourceAdaptationProcessorListener::OnVideoSourceRestrictionsUpdated()? Both
+// listen to adaptations being applied, but on different layers with different
+// arguments.
+class AdaptationListener {
+ public:
+  virtual ~AdaptationListener();
+
+  // TODO(https://crbug.com/webrtc/11172): When we have multi-stream adaptation
+  // support, this interface needs to indicate which stream the adaptation
+  // applies to.
+  virtual void OnAdaptationApplied(
+      const VideoStreamInputState& input_state,
+      const VideoSourceRestrictions& restrictions_before,
+      const VideoSourceRestrictions& restrictions_after,
+      rtc::scoped_refptr<Resource> reason_resource) = 0;
+};
+
+}  // namespace webrtc
+
+#endif  // CALL_ADAPTATION_ADAPTATION_LISTENER_H_
diff --git a/call/adaptation/resource.h b/call/adaptation/resource.h
index febc29c..ddc0fe8 100644
--- a/call/adaptation/resource.h
+++ b/call/adaptation/resource.h
@@ -48,8 +48,8 @@
 // kOveruse or kUnderuse when resource usage is high or low enough that we
 // should perform some sort of mitigation to fulfil the resource's constraints.
 //
-// All methods defined in this interface, except RegisterAdaptationTaskQueue(),
-// MUST be invoked on the resource adaptation task queue.
+// All methods defined in this interface, except SetResourceListener(), MUST be
+// invoked on the resource adaptation task queue.
 //
 // Usage measurements may be performed on an implementation-specific task queue.
 // The Resource is reference counted to prevent use-after-free when posting
@@ -61,21 +61,9 @@
   // Destruction may happen on any task queue.
   ~Resource() override;
 
-  // Provides a pointer to the adaptation task queue. After this call, all
-  // methods defined in this interface, including
-  // UnregisterAdaptationTaskQueue() MUST be invoked on the adaptation task
-  // queue. Registering the adaptation task queue may, however, happen off the
-  // adaptation task queue.
-  virtual void RegisterAdaptationTaskQueue(
-      TaskQueueBase* resource_adaptation_queue) = 0;
-  // Signals that the adaptation task queue is no longer safe to use. No
-  // assumptions must be made as to whether or not tasks in-flight will run.
-  virtual void UnregisterAdaptationTaskQueue() = 0;
-
-  // The listeners MUST be informed any time UsageState() changes.
-  virtual void SetResourceListener(ResourceListener* listener) = 0;
-
   virtual std::string Name() const = 0;
+  // The listener MUST be informed any time UsageState() changes.
+  virtual void SetResourceListener(ResourceListener* listener) = 0;
   // Within a single task running on the adaptation task queue, UsageState()
   // MUST return the same value every time it is called.
   // TODO(https://crbug.com/webrtc/11618): Remove the UsageState() getter in
@@ -86,20 +74,6 @@
   // Invalidates current usage measurements, i.e. in response to the system load
   // changing. Example: an adaptation was just applied.
   virtual void ClearUsageState() = 0;
-
-  // This method allows the Resource to reject a proposed adaptation in the "up"
-  // direction if it predicts this would cause overuse of this resource.
-  virtual bool IsAdaptationUpAllowed(
-      const VideoStreamInputState& input_state,
-      const VideoSourceRestrictions& restrictions_before,
-      const VideoSourceRestrictions& restrictions_after,
-      rtc::scoped_refptr<Resource> reason_resource) const = 0;
-
-  virtual void OnAdaptationApplied(
-      const VideoStreamInputState& input_state,
-      const VideoSourceRestrictions& restrictions_before,
-      const VideoSourceRestrictions& restrictions_after,
-      rtc::scoped_refptr<Resource> reason_resource) = 0;
 };
 
 }  // namespace webrtc
diff --git a/call/adaptation/resource_adaptation_processor.cc b/call/adaptation/resource_adaptation_processor.cc
index a705ccf..ed8f78d 100644
--- a/call/adaptation/resource_adaptation_processor.cc
+++ b/call/adaptation/resource_adaptation_processor.cc
@@ -49,12 +49,18 @@
 ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   RTC_DCHECK(!is_resource_adaptation_enabled_);
-  RTC_DCHECK(adaptation_listeners_.empty())
-      << "There are listener(s) depending on a ResourceAdaptationProcessor "
-      << "being destroyed.";
+  RTC_DCHECK(restrictions_listeners_.empty())
+      << "There are restrictions listener(s) depending on a "
+      << "ResourceAdaptationProcessor being destroyed.";
   RTC_DCHECK(resources_.empty())
       << "There are resource(s) attached to a ResourceAdaptationProcessor "
       << "being destroyed.";
+  RTC_DCHECK(adaptation_constraints_.empty())
+      << "There are constaint(s) attached to a ResourceAdaptationProcessor "
+      << "being destroyed.";
+  RTC_DCHECK(adaptation_listeners_.empty())
+      << "There are listener(s) attached to a ResourceAdaptationProcessor "
+      << "being destroyed.";
 }
 
 void ResourceAdaptationProcessor::InitializeOnResourceAdaptationQueue() {
@@ -95,22 +101,22 @@
   is_resource_adaptation_enabled_ = false;
 }
 
-void ResourceAdaptationProcessor::AddAdaptationListener(
-    ResourceAdaptationProcessorListener* adaptation_listener) {
+void ResourceAdaptationProcessor::AddRestrictionsListener(
+    VideoSourceRestrictionsListener* restrictions_listener) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  RTC_DCHECK(std::find(adaptation_listeners_.begin(),
-                       adaptation_listeners_.end(),
-                       adaptation_listener) == adaptation_listeners_.end());
-  adaptation_listeners_.push_back(adaptation_listener);
+  RTC_DCHECK(std::find(restrictions_listeners_.begin(),
+                       restrictions_listeners_.end(),
+                       restrictions_listener) == restrictions_listeners_.end());
+  restrictions_listeners_.push_back(restrictions_listener);
 }
 
-void ResourceAdaptationProcessor::RemoveAdaptationListener(
-    ResourceAdaptationProcessorListener* adaptation_listener) {
+void ResourceAdaptationProcessor::RemoveRestrictionsListener(
+    VideoSourceRestrictionsListener* restrictions_listener) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  auto it = std::find(adaptation_listeners_.begin(),
-                      adaptation_listeners_.end(), adaptation_listener);
-  RTC_DCHECK(it != adaptation_listeners_.end());
-  adaptation_listeners_.erase(it);
+  auto it = std::find(restrictions_listeners_.begin(),
+                      restrictions_listeners_.end(), restrictions_listener);
+  RTC_DCHECK(it != restrictions_listeners_.end());
+  restrictions_listeners_.erase(it);
 }
 
 void ResourceAdaptationProcessor::AddResource(
@@ -136,6 +142,42 @@
   resources_.erase(it);
 }
 
+void ResourceAdaptationProcessor::AddAdaptationConstraint(
+    AdaptationConstraint* adaptation_constraint) {
+  RTC_DCHECK_RUN_ON(&sequence_checker_);
+  RTC_DCHECK(std::find(adaptation_constraints_.begin(),
+                       adaptation_constraints_.end(),
+                       adaptation_constraint) == adaptation_constraints_.end());
+  adaptation_constraints_.push_back(adaptation_constraint);
+}
+
+void ResourceAdaptationProcessor::RemoveAdaptationConstraint(
+    AdaptationConstraint* adaptation_constraint) {
+  RTC_DCHECK_RUN_ON(&sequence_checker_);
+  auto it = std::find(adaptation_constraints_.begin(),
+                      adaptation_constraints_.end(), adaptation_constraint);
+  RTC_DCHECK(it != adaptation_constraints_.end());
+  adaptation_constraints_.erase(it);
+}
+
+void ResourceAdaptationProcessor::AddAdaptationListener(
+    AdaptationListener* adaptation_listener) {
+  RTC_DCHECK_RUN_ON(&sequence_checker_);
+  RTC_DCHECK(std::find(adaptation_listeners_.begin(),
+                       adaptation_listeners_.end(),
+                       adaptation_listener) == adaptation_listeners_.end());
+  adaptation_listeners_.push_back(adaptation_listener);
+}
+
+void ResourceAdaptationProcessor::RemoveAdaptationListener(
+    AdaptationListener* adaptation_listener) {
+  RTC_DCHECK_RUN_ON(&sequence_checker_);
+  auto it = std::find(adaptation_listeners_.begin(),
+                      adaptation_listeners_.end(), adaptation_listener);
+  RTC_DCHECK(it != adaptation_listeners_.end());
+  adaptation_listeners_.erase(it);
+}
+
 void ResourceAdaptationProcessor::SetDegradationPreference(
     DegradationPreference degradation_preference) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
@@ -181,8 +223,8 @@
                          effective_degradation_preference_)
                   << "): " << new_source_restrictions.ToString();
     last_reported_source_restrictions_ = std::move(new_source_restrictions);
-    for (auto* adaptation_listener : adaptation_listeners_) {
-      adaptation_listener->OnVideoSourceRestrictionsUpdated(
+    for (auto* restrictions_listener : restrictions_listeners_) {
+      restrictions_listener->OnVideoSourceRestrictionsUpdated(
           last_reported_source_restrictions_,
           stream_adapter_->adaptation_counters(), reason);
     }
@@ -284,25 +326,26 @@
       stream_adapter_->source_restrictions();
   VideoSourceRestrictions restrictions_after =
       stream_adapter_->PeekNextRestrictions(adaptation);
-  for (const auto& resource : resources_) {
-    if (!resource->IsAdaptationUpAllowed(input_state, restrictions_before,
-                                         restrictions_after, reason_resource)) {
+  for (const auto* constraint : adaptation_constraints_) {
+    if (!constraint->IsAdaptationUpAllowed(input_state, restrictions_before,
+                                           restrictions_after,
+                                           reason_resource)) {
       processing_in_progress_ = false;
       rtc::StringBuilder message;
-      message << "Not adapting up because resource \"" << resource->Name()
+      message << "Not adapting up because constraint \"" << constraint->Name()
               << "\" disallowed it";
       return MitigationResultAndLogMessage(
-          MitigationResult::kRejectedByResource, message.Release());
+          MitigationResult::kRejectedByConstraint, message.Release());
     }
   }
   // Apply adaptation.
   stream_adapter_->ApplyAdaptation(adaptation);
-  for (const auto& resource : resources_) {
-    resource->OnAdaptationApplied(input_state, restrictions_before,
-                                  restrictions_after, reason_resource);
+  for (auto* adaptation_listener : adaptation_listeners_) {
+    adaptation_listener->OnAdaptationApplied(
+        input_state, restrictions_before, restrictions_after, reason_resource);
   }
   // Update VideoSourceRestrictions based on adaptation. This also informs the
-  // |adaptation_listeners_|.
+  // |restrictions_listeners_|.
   MaybeUpdateVideoSourceRestrictions(reason_resource);
   processing_in_progress_ = false;
   rtc::StringBuilder message;
@@ -359,12 +402,12 @@
   VideoSourceRestrictions restrictions_after =
       stream_adapter_->PeekNextRestrictions(adaptation);
   stream_adapter_->ApplyAdaptation(adaptation);
-  for (const auto& resource : resources_) {
-    resource->OnAdaptationApplied(input_state, restrictions_before,
-                                  restrictions_after, reason_resource);
+  for (auto* adaptation_listener : adaptation_listeners_) {
+    adaptation_listener->OnAdaptationApplied(
+        input_state, restrictions_before, restrictions_after, reason_resource);
   }
   // Update VideoSourceRestrictions based on adaptation. This also informs the
-  // |adaptation_listeners_|.
+  // |restrictions_listeners_|.
   MaybeUpdateVideoSourceRestrictions(reason_resource);
   processing_in_progress_ = false;
   rtc::StringBuilder message;
diff --git a/call/adaptation/resource_adaptation_processor.h b/call/adaptation/resource_adaptation_processor.h
index 06b9a4c..7988439 100644
--- a/call/adaptation/resource_adaptation_processor.h
+++ b/call/adaptation/resource_adaptation_processor.h
@@ -21,6 +21,8 @@
 #include "api/scoped_refptr.h"
 #include "api/video/video_frame.h"
 #include "api/video/video_stream_encoder_observer.h"
+#include "call/adaptation/adaptation_constraint.h"
+#include "call/adaptation/adaptation_listener.h"
 #include "call/adaptation/resource.h"
 #include "call/adaptation/resource_adaptation_processor_interface.h"
 #include "call/adaptation/video_source_restrictions.h"
@@ -63,12 +65,19 @@
 
   void StartResourceAdaptation() override;
   void StopResourceAdaptation() override;
-  void AddAdaptationListener(
-      ResourceAdaptationProcessorListener* adaptation_listener) override;
-  void RemoveAdaptationListener(
-      ResourceAdaptationProcessorListener* adaptation_listener) override;
+  void AddRestrictionsListener(
+      VideoSourceRestrictionsListener* restrictions_listener) override;
+  void RemoveRestrictionsListener(
+      VideoSourceRestrictionsListener* restrictions_listener) override;
   void AddResource(rtc::scoped_refptr<Resource> resource) override;
   void RemoveResource(rtc::scoped_refptr<Resource> resource) override;
+  void AddAdaptationConstraint(
+      AdaptationConstraint* adaptation_constraint) override;
+  void RemoveAdaptationConstraint(
+      AdaptationConstraint* adaptation_constraint) override;
+  void AddAdaptationListener(AdaptationListener* adaptation_listener) override;
+  void RemoveAdaptationListener(
+      AdaptationListener* adaptation_listener) override;
 
   void SetDegradationPreference(
       DegradationPreference degradation_preference) override;
@@ -95,7 +104,7 @@
     kInsufficientInput,
     kRejectedByAdaptationCounts,
     kRejectedByAdapter,
-    kRejectedByResource,
+    kRejectedByConstraint,
     kAdaptationApplied,
   };
 
@@ -139,10 +148,14 @@
       RTC_GUARDED_BY(sequence_checker_);
   VideoStreamEncoderObserver* const encoder_stats_observer_
       RTC_GUARDED_BY(sequence_checker_);
-  std::vector<ResourceAdaptationProcessorListener*> adaptation_listeners_
+  std::vector<VideoSourceRestrictionsListener*> restrictions_listeners_
       RTC_GUARDED_BY(sequence_checker_);
   std::vector<rtc::scoped_refptr<Resource>> resources_
       RTC_GUARDED_BY(sequence_checker_);
+  std::vector<AdaptationConstraint*> adaptation_constraints_
+      RTC_GUARDED_BY(sequence_checker_);
+  std::vector<AdaptationListener*> adaptation_listeners_
+      RTC_GUARDED_BY(sequence_checker_);
   // Purely used for statistics, does not ensure mapped resources stay alive.
   std::map<const Resource*, int> adaptations_counts_by_resource_
       RTC_GUARDED_BY(sequence_checker_);
diff --git a/call/adaptation/resource_adaptation_processor_interface.cc b/call/adaptation/resource_adaptation_processor_interface.cc
index 4e5251c..f7381d3 100644
--- a/call/adaptation/resource_adaptation_processor_interface.cc
+++ b/call/adaptation/resource_adaptation_processor_interface.cc
@@ -12,7 +12,7 @@
 
 namespace webrtc {
 
-ResourceAdaptationProcessorListener::~ResourceAdaptationProcessorListener() {}
+VideoSourceRestrictionsListener::~VideoSourceRestrictionsListener() {}
 
 ResourceAdaptationProcessorInterface::~ResourceAdaptationProcessorInterface() {}
 
diff --git a/call/adaptation/resource_adaptation_processor_interface.h b/call/adaptation/resource_adaptation_processor_interface.h
index d6295c4..8dafefa 100644
--- a/call/adaptation/resource_adaptation_processor_interface.h
+++ b/call/adaptation/resource_adaptation_processor_interface.h
@@ -16,6 +16,8 @@
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_counters.h"
 #include "api/video/video_frame.h"
+#include "call/adaptation/adaptation_constraint.h"
+#include "call/adaptation/adaptation_listener.h"
 #include "call/adaptation/encoder_settings.h"
 #include "call/adaptation/resource.h"
 #include "call/adaptation/video_source_restrictions.h"
@@ -25,9 +27,9 @@
 
 // The listener is responsible for carrying out the reconfiguration of the video
 // source such that the VideoSourceRestrictions are fulfilled.
-class ResourceAdaptationProcessorListener {
+class VideoSourceRestrictionsListener {
  public:
-  virtual ~ResourceAdaptationProcessorListener();
+  virtual ~VideoSourceRestrictionsListener();
 
   // The |restrictions| are filtered by degradation preference but not the
   // |adaptation_counters|, which are currently only reported for legacy stats
@@ -63,12 +65,20 @@
   // over time.
   virtual void StartResourceAdaptation() = 0;
   virtual void StopResourceAdaptation() = 0;
-  virtual void AddAdaptationListener(
-      ResourceAdaptationProcessorListener* adaptation_listener) = 0;
-  virtual void RemoveAdaptationListener(
-      ResourceAdaptationProcessorListener* adaptation_listener) = 0;
+  virtual void AddRestrictionsListener(
+      VideoSourceRestrictionsListener* restrictions_listener) = 0;
+  virtual void RemoveRestrictionsListener(
+      VideoSourceRestrictionsListener* restrictions_listener) = 0;
   virtual void AddResource(rtc::scoped_refptr<Resource> resource) = 0;
   virtual void RemoveResource(rtc::scoped_refptr<Resource> resource) = 0;
+  virtual void AddAdaptationConstraint(
+      AdaptationConstraint* adaptation_constraint) = 0;
+  virtual void RemoveAdaptationConstraint(
+      AdaptationConstraint* adaptation_constraint) = 0;
+  virtual void AddAdaptationListener(
+      AdaptationListener* adaptation_listener) = 0;
+  virtual void RemoveAdaptationListener(
+      AdaptationListener* adaptation_listener) = 0;
 
   virtual void SetDegradationPreference(
       DegradationPreference degradation_preference) = 0;
diff --git a/call/adaptation/resource_adaptation_processor_unittest.cc b/call/adaptation/resource_adaptation_processor_unittest.cc
index c150700..6ff24b1 100644
--- a/call/adaptation/resource_adaptation_processor_unittest.cc
+++ b/call/adaptation/resource_adaptation_processor_unittest.cc
@@ -14,6 +14,8 @@
 #include "api/video/video_adaptation_counters.h"
 #include "call/adaptation/resource.h"
 #include "call/adaptation/resource_adaptation_processor_interface.h"
+#include "call/adaptation/test/fake_adaptation_constraint.h"
+#include "call/adaptation/test/fake_adaptation_listener.h"
 #include "call/adaptation/test/fake_frame_rate_provider.h"
 #include "call/adaptation/test/fake_resource.h"
 #include "call/adaptation/video_source_restrictions.h"
@@ -29,15 +31,15 @@
 const int kDefaultFrameRate = 30;
 const int kDefaultFrameSize = 1280 * 720;
 
-class ResourceAdaptationProcessorListenerForTesting
-    : public ResourceAdaptationProcessorListener {
+class VideoSourceRestrictionsListenerForTesting
+    : public VideoSourceRestrictionsListener {
  public:
-  ResourceAdaptationProcessorListenerForTesting()
+  VideoSourceRestrictionsListenerForTesting()
       : restrictions_updated_count_(0),
         restrictions_(),
         adaptation_counters_(),
         reason_(nullptr) {}
-  ~ResourceAdaptationProcessorListenerForTesting() override {}
+  ~VideoSourceRestrictionsListenerForTesting() override {}
 
   size_t restrictions_updated_count() const {
     return restrictions_updated_count_;
@@ -48,7 +50,7 @@
   }
   rtc::scoped_refptr<Resource> reason() const { return reason_; }
 
-  // ResourceAdaptationProcessorListener implementation.
+  // VideoSourceRestrictionsListener implementation.
   void OnVideoSourceRestrictionsUpdated(
       VideoSourceRestrictions restrictions,
       const VideoAdaptationCounters& adaptation_counters,
@@ -74,18 +76,19 @@
         input_state_provider_(&frame_rate_provider_),
         resource_(FakeResource::Create("FakeResource")),
         other_resource_(FakeResource::Create("OtherFakeResource")),
+        adaptation_constraint_("FakeAdaptationConstraint"),
+        adaptation_listener_(),
         processor_(std::make_unique<ResourceAdaptationProcessor>(
             &input_state_provider_,
             /*encoder_stats_observer=*/&frame_rate_provider_)) {
-    resource_->RegisterAdaptationTaskQueue(resource_adaptation_queue_.Get());
-    other_resource_->RegisterAdaptationTaskQueue(
-        resource_adaptation_queue_.Get());
     rtc::Event event;
     resource_adaptation_queue_.PostTask([this, &event] {
       processor_->InitializeOnResourceAdaptationQueue();
-      processor_->AddAdaptationListener(&processor_listener_);
+      processor_->AddRestrictionsListener(&restrictions_listener_);
       processor_->AddResource(resource_);
       processor_->AddResource(other_resource_);
+      processor_->AddAdaptationConstraint(&adaptation_constraint_);
+      processor_->AddAdaptationListener(&adaptation_listener_);
       event.Set();
     });
     event.Wait(rtc::Event::kForever);
@@ -94,9 +97,11 @@
     rtc::Event event;
     resource_adaptation_queue_.PostTask([this, &event] {
       processor_->StopResourceAdaptation();
+      processor_->RemoveRestrictionsListener(&restrictions_listener_);
       processor_->RemoveResource(resource_);
       processor_->RemoveResource(other_resource_);
-      processor_->RemoveAdaptationListener(&processor_listener_);
+      processor_->RemoveAdaptationConstraint(&adaptation_constraint_);
+      processor_->RemoveAdaptationListener(&adaptation_listener_);
       processor_.reset();
       event.Set();
     });
@@ -123,8 +128,10 @@
   VideoStreamInputStateProvider input_state_provider_;
   rtc::scoped_refptr<FakeResource> resource_;
   rtc::scoped_refptr<FakeResource> other_resource_;
+  FakeAdaptationConstraint adaptation_constraint_;
+  FakeAdaptationListener adaptation_listener_;
   std::unique_ptr<ResourceAdaptationProcessor> processor_;
-  ResourceAdaptationProcessorListenerForTesting processor_listener_;
+  VideoSourceRestrictionsListenerForTesting restrictions_listener_;
 };
 
 }  // namespace
@@ -139,8 +146,8 @@
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
         processor_->StartResourceAdaptation();
         // Adaptation does not happen when disabled.
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
       },
       RTC_FROM_HERE);
 }
@@ -154,12 +161,12 @@
         // Adaptation does not happen if input is insufficient.
         // When frame size is missing (OnFrameSizeObserved not called yet).
         input_state_provider_.OnHasInputChanged(true);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
         // When "has input" is missing.
         SetInputStates(false, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
         // Note: frame rate cannot be missing, if unset it is 0.
       },
       RTC_FROM_HERE);
@@ -177,9 +184,9 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
-        EXPECT_TRUE(processor_listener_.restrictions()
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
+        EXPECT_TRUE(restrictions_listener_.restrictions()
                         .max_pixels_per_frame()
                         .has_value());
       },
@@ -194,10 +201,10 @@
             DegradationPreference::MAINTAIN_RESOLUTION);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
         EXPECT_TRUE(
-            processor_listener_.restrictions().max_frame_rate().has_value());
+            restrictions_listener_.restrictions().max_frame_rate().has_value());
       },
       RTC_FROM_HERE);
 }
@@ -214,15 +221,15 @@
         // BalancedDegradationSettings, VideoStreamAdapter and default input
         // states. This test requires it to be achieved within 4 adaptations.
         for (size_t i = 0; i < 4; ++i) {
-          resource_->set_usage_state(ResourceUsageState::kOveruse);
-          EXPECT_EQ(i + 1, processor_listener_.restrictions_updated_count());
-          RestrictSource(processor_listener_.restrictions());
+          resource_->SetUsageState(ResourceUsageState::kOveruse);
+          EXPECT_EQ(i + 1, restrictions_listener_.restrictions_updated_count());
+          RestrictSource(restrictions_listener_.restrictions());
         }
-        EXPECT_TRUE(processor_listener_.restrictions()
+        EXPECT_TRUE(restrictions_listener_.restrictions()
                         .max_pixels_per_frame()
                         .has_value());
         EXPECT_TRUE(
-            processor_listener_.restrictions().max_frame_rate().has_value());
+            restrictions_listener_.restrictions().max_frame_rate().has_value());
       },
       RTC_FROM_HERE);
 }
@@ -234,12 +241,12 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
         // If we don't restrict the source then adaptation will not happen again
         // due to "awaiting previous adaptation". This prevents "double-adapt".
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
       },
       RTC_FROM_HERE);
 }
@@ -251,8 +258,8 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
       },
       RTC_FROM_HERE);
 }
@@ -264,13 +271,13 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
-        RestrictSource(processor_listener_.restrictions());
-        resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(2u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
+        RestrictSource(restrictions_listener_.restrictions());
+        resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(2u, restrictions_listener_.restrictions_updated_count());
         EXPECT_EQ(VideoSourceRestrictions(),
-                  processor_listener_.restrictions());
+                  restrictions_listener_.restrictions());
       },
       RTC_FROM_HERE);
 }
@@ -283,13 +290,13 @@
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
         // Adapt down so that we can adapt up.
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
-        RestrictSource(processor_listener_.restrictions());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
+        RestrictSource(restrictions_listener_.restrictions());
         // Adapting up is prevented.
-        resource_->set_is_adaptation_up_allowed(false);
-        resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
+        adaptation_constraint_.set_is_adaptation_up_allowed(false);
+        resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
       },
       RTC_FROM_HERE);
 }
@@ -302,13 +309,13 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
-        RestrictSource(processor_listener_.restrictions());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
+        RestrictSource(restrictions_listener_.restrictions());
 
         // Other resource signals under-use
-        other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
+        other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
       },
       RTC_FROM_HERE);
 }
@@ -321,19 +328,19 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
 
         processor_->ResetVideoSourceRestrictions();
-        EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
-        other_resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
+        EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
+        other_resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
 
         // resource_ did not overuse after we reset the restrictions, so adapt
         // up should be disallowed.
-        resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
+        resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
       },
       RTC_FROM_HERE);
 }
@@ -346,30 +353,30 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
-        other_resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
-        other_resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(3, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
+        other_resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
+        other_resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
 
-        resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
+        resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
         // Does not trigger adaptation since resource has no adaptations left.
-        resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
+        resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
 
-        other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
-        other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
-        EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
+        other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
+        other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
+        EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
       },
       RTC_FROM_HERE);
 }
@@ -381,8 +388,8 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, resource_->num_adaptations_applied());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, adaptation_listener_.num_adaptations_applied());
       },
       RTC_FROM_HERE);
 }
@@ -394,8 +401,8 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
         EXPECT_FALSE(resource_->UsageState().has_value());
       },
       RTC_FROM_HERE);
@@ -407,8 +414,8 @@
       [this] {
         processor_->SetDegradationPreference(DegradationPreference::DISABLED);
         processor_->StartResourceAdaptation();
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
-        EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
+        EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
         EXPECT_FALSE(resource_->UsageState().has_value());
       },
       RTC_FROM_HERE);
@@ -422,20 +429,20 @@
             DegradationPreference::MAINTAIN_FRAMERATE);
         processor_->StartResourceAdaptation();
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
-        other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
+        other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
         // Does not trigger adapataion because there's no restriction.
-        EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
+        EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
 
-        RestrictSource(processor_listener_.restrictions());
-        resource_->set_usage_state(ResourceUsageState::kOveruse);
+        RestrictSource(restrictions_listener_.restrictions());
+        resource_->SetUsageState(ResourceUsageState::kOveruse);
         // Adapts down even if other resource asked for adapting up.
-        EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
+        EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
 
-        RestrictSource(processor_listener_.restrictions());
-        other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
+        RestrictSource(restrictions_listener_.restrictions());
+        other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
         // Doesn't adapt up because adaptation is due to another resource.
-        EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
-        RestrictSource(processor_listener_.restrictions());
+        EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
+        RestrictSource(restrictions_listener_.restrictions());
       },
       RTC_FROM_HERE);
 }
diff --git a/call/adaptation/resource_unittest.cc b/call/adaptation/resource_unittest.cc
index ad93fbd..afa32f0 100644
--- a/call/adaptation/resource_unittest.cc
+++ b/call/adaptation/resource_unittest.cc
@@ -14,8 +14,6 @@
 
 #include "api/scoped_refptr.h"
 #include "call/adaptation/test/fake_resource.h"
-#include "rtc_base/event.h"
-#include "rtc_base/task_queue_for_test.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
 
@@ -34,46 +32,30 @@
 
 class ResourceTest : public ::testing::Test {
  public:
-  ResourceTest()
-      : resource_adaptation_queue_("ResourceAdaptationQueue"),
-        fake_resource_(FakeResource::Create("FakeResource")) {
-    fake_resource_->RegisterAdaptationTaskQueue(
-        resource_adaptation_queue_.Get());
-  }
+  ResourceTest() : fake_resource_(FakeResource::Create("FakeResource")) {}
 
  protected:
-  const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
-  TaskQueueForTest resource_adaptation_queue_;
   rtc::scoped_refptr<FakeResource> fake_resource_;
 };
 
 TEST_F(ResourceTest, RegisteringListenerReceivesCallbacks) {
-  resource_adaptation_queue_.SendTask(
-      [this] {
-        StrictMock<MockResourceListener> resource_listener;
-        fake_resource_->SetResourceListener(&resource_listener);
-        EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
-            .Times(1)
-            .WillOnce([](rtc::scoped_refptr<Resource> resource) {
-              EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
-            });
-        fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
-        fake_resource_->SetResourceListener(nullptr);
-      },
-      RTC_FROM_HERE);
+  StrictMock<MockResourceListener> resource_listener;
+  fake_resource_->SetResourceListener(&resource_listener);
+  EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
+      .Times(1)
+      .WillOnce([](rtc::scoped_refptr<Resource> resource) {
+        EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
+      });
+  fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
+  fake_resource_->SetResourceListener(nullptr);
 }
 
 TEST_F(ResourceTest, UnregisteringListenerStopsCallbacks) {
-  resource_adaptation_queue_.SendTask(
-      [this] {
-        StrictMock<MockResourceListener> resource_listener;
-        fake_resource_->SetResourceListener(&resource_listener);
-        fake_resource_->SetResourceListener(nullptr);
-        EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
-            .Times(0);
-        fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
-      },
-      RTC_FROM_HERE);
+  StrictMock<MockResourceListener> resource_listener;
+  fake_resource_->SetResourceListener(&resource_listener);
+  fake_resource_->SetResourceListener(nullptr);
+  EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_)).Times(0);
+  fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
 }
 
 }  // namespace webrtc
diff --git a/call/adaptation/test/fake_adaptation_constraint.cc b/call/adaptation/test/fake_adaptation_constraint.cc
new file mode 100644
index 0000000..983885e
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_constraint.cc
@@ -0,0 +1,39 @@
+/*
+ *  Copyright 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/test/fake_adaptation_constraint.h"
+
+#include <utility>
+
+namespace webrtc {
+
+FakeAdaptationConstraint::FakeAdaptationConstraint(std::string name)
+    : name_(std::move(name)), is_adaptation_up_allowed_(true) {}
+
+FakeAdaptationConstraint::~FakeAdaptationConstraint() {}
+
+void FakeAdaptationConstraint::set_is_adaptation_up_allowed(
+    bool is_adaptation_up_allowed) {
+  is_adaptation_up_allowed_ = is_adaptation_up_allowed;
+}
+
+std::string FakeAdaptationConstraint::Name() const {
+  return name_;
+}
+
+bool FakeAdaptationConstraint::IsAdaptationUpAllowed(
+    const VideoStreamInputState& input_state,
+    const VideoSourceRestrictions& restrictions_before,
+    const VideoSourceRestrictions& restrictions_after,
+    rtc::scoped_refptr<Resource> reason_resource) const {
+  return is_adaptation_up_allowed_;
+}
+
+}  // namespace webrtc
diff --git a/call/adaptation/test/fake_adaptation_constraint.h b/call/adaptation/test/fake_adaptation_constraint.h
new file mode 100644
index 0000000..74637f4
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_constraint.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright 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.
+ */
+
+#ifndef CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
+#define CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
+
+#include <string>
+
+#include "call/adaptation/adaptation_constraint.h"
+
+namespace webrtc {
+
+class FakeAdaptationConstraint : public AdaptationConstraint {
+ public:
+  explicit FakeAdaptationConstraint(std::string name);
+  ~FakeAdaptationConstraint() override;
+
+  void set_is_adaptation_up_allowed(bool is_adaptation_up_allowed);
+
+  // AdaptationConstraint implementation.
+  std::string Name() const override;
+  bool IsAdaptationUpAllowed(
+      const VideoStreamInputState& input_state,
+      const VideoSourceRestrictions& restrictions_before,
+      const VideoSourceRestrictions& restrictions_after,
+      rtc::scoped_refptr<Resource> reason_resource) const override;
+
+ private:
+  const std::string name_;
+  bool is_adaptation_up_allowed_;
+};
+
+}  // namespace webrtc
+
+#endif  // CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
diff --git a/call/adaptation/test/fake_adaptation_listener.cc b/call/adaptation/test/fake_adaptation_listener.cc
new file mode 100644
index 0000000..7feecd6
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_listener.cc
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 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/test/fake_adaptation_listener.h"
+
+namespace webrtc {
+
+FakeAdaptationListener::FakeAdaptationListener()
+    : num_adaptations_applied_(0) {}
+
+FakeAdaptationListener::~FakeAdaptationListener() {}
+
+size_t FakeAdaptationListener::num_adaptations_applied() const {
+  return num_adaptations_applied_;
+}
+
+void FakeAdaptationListener::OnAdaptationApplied(
+    const VideoStreamInputState& input_state,
+    const VideoSourceRestrictions& restrictions_before,
+    const VideoSourceRestrictions& restrictions_after,
+    rtc::scoped_refptr<Resource> reason_resource) {
+  ++num_adaptations_applied_;
+}
+
+}  // namespace webrtc
diff --git a/call/adaptation/test/fake_adaptation_listener.h b/call/adaptation/test/fake_adaptation_listener.h
new file mode 100644
index 0000000..c60ba30
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_listener.h
@@ -0,0 +1,38 @@
+/*
+ *  Copyright 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.
+ */
+
+#ifndef CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
+#define CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
+
+#include "call/adaptation/adaptation_listener.h"
+
+namespace webrtc {
+
+class FakeAdaptationListener : public AdaptationListener {
+ public:
+  FakeAdaptationListener();
+  ~FakeAdaptationListener() override;
+
+  size_t num_adaptations_applied() const;
+
+  // AdaptationListener implementation.
+  void OnAdaptationApplied(
+      const VideoStreamInputState& input_state,
+      const VideoSourceRestrictions& restrictions_before,
+      const VideoSourceRestrictions& restrictions_after,
+      rtc::scoped_refptr<Resource> reason_resource) override;
+
+ private:
+  size_t num_adaptations_applied_;
+};
+
+}  // namespace webrtc
+
+#endif  // CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
diff --git a/call/adaptation/test/fake_resource.cc b/call/adaptation/test/fake_resource.cc
index fef765b..113f4b5 100644
--- a/call/adaptation/test/fake_resource.cc
+++ b/call/adaptation/test/fake_resource.cc
@@ -14,7 +14,6 @@
 #include <utility>
 
 #include "rtc_base/ref_counted_object.h"
-#include "rtc_base/task_utils/to_queued_task.h"
 
 namespace webrtc {
 
@@ -25,91 +24,33 @@
 
 FakeResource::FakeResource(std::string name)
     : Resource(),
-      lock_(),
       name_(std::move(name)),
-      resource_adaptation_queue_(nullptr),
-      is_adaptation_up_allowed_(true),
-      num_adaptations_applied_(0),
-      usage_state_(absl::nullopt),
-      listener_(nullptr) {}
+      listener_(nullptr),
+      usage_state_(absl::nullopt) {}
 
 FakeResource::~FakeResource() {}
 
-void FakeResource::set_usage_state(ResourceUsageState usage_state) {
-  if (!resource_adaptation_queue_->IsCurrent()) {
-    resource_adaptation_queue_->PostTask(ToQueuedTask(
-        [this_ref = rtc::scoped_refptr<FakeResource>(this), usage_state] {
-          this_ref->set_usage_state(usage_state);
-        }));
-    return;
-  }
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
+void FakeResource::SetUsageState(ResourceUsageState usage_state) {
   usage_state_ = usage_state;
   if (listener_) {
     listener_->OnResourceUsageStateMeasured(this);
   }
 }
 
-void FakeResource::set_is_adaptation_up_allowed(bool is_adaptation_up_allowed) {
-  rtc::CritScope crit(&lock_);
-  is_adaptation_up_allowed_ = is_adaptation_up_allowed;
-}
-
-size_t FakeResource::num_adaptations_applied() const {
-  rtc::CritScope crit(&lock_);
-  return num_adaptations_applied_;
-}
-
-void FakeResource::RegisterAdaptationTaskQueue(
-    TaskQueueBase* resource_adaptation_queue) {
-  RTC_DCHECK(!resource_adaptation_queue_);
-  RTC_DCHECK(resource_adaptation_queue);
-  resource_adaptation_queue_ = resource_adaptation_queue;
-}
-
-void FakeResource::UnregisterAdaptationTaskQueue() {
-  RTC_DCHECK(resource_adaptation_queue_);
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  resource_adaptation_queue_ = nullptr;
-}
-
-void FakeResource::SetResourceListener(ResourceListener* listener) {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  listener_ = listener;
-}
-
 std::string FakeResource::Name() const {
   return name_;
 }
 
+void FakeResource::SetResourceListener(ResourceListener* listener) {
+  listener_ = listener;
+}
+
 absl::optional<ResourceUsageState> FakeResource::UsageState() const {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   return usage_state_;
 }
 
 void FakeResource::ClearUsageState() {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   usage_state_ = absl::nullopt;
 }
 
-bool FakeResource::IsAdaptationUpAllowed(
-    const VideoStreamInputState& input_state,
-    const VideoSourceRestrictions& restrictions_before,
-    const VideoSourceRestrictions& restrictions_after,
-    rtc::scoped_refptr<Resource> reason_resource) const {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  rtc::CritScope crit(&lock_);
-  return is_adaptation_up_allowed_;
-}
-
-void FakeResource::OnAdaptationApplied(
-    const VideoStreamInputState& input_state,
-    const VideoSourceRestrictions& restrictions_before,
-    const VideoSourceRestrictions& restrictions_after,
-    rtc::scoped_refptr<Resource> reason_resource) {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  rtc::CritScope crit(&lock_);
-  ++num_adaptations_applied_;
-}
-
 }  // namespace webrtc
diff --git a/call/adaptation/test/fake_resource.h b/call/adaptation/test/fake_resource.h
index 19f93ad..c67dc3a 100644
--- a/call/adaptation/test/fake_resource.h
+++ b/call/adaptation/test/fake_resource.h
@@ -16,10 +16,7 @@
 
 #include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
-#include "api/task_queue/task_queue_base.h"
 #include "call/adaptation/resource.h"
-#include "rtc_base/critical_section.h"
-#include "rtc_base/synchronization/sequence_checker.h"
 
 namespace webrtc {
 
@@ -31,38 +28,18 @@
   explicit FakeResource(std::string name);
   ~FakeResource() override;
 
-  void set_usage_state(ResourceUsageState usage_state);
-  void set_is_adaptation_up_allowed(bool is_adaptation_up_allowed);
-  size_t num_adaptations_applied() const;
+  void SetUsageState(ResourceUsageState usage_state);
 
   // Resource implementation.
-  void RegisterAdaptationTaskQueue(
-      TaskQueueBase* resource_adaptation_queue) override;
-  void UnregisterAdaptationTaskQueue() override;
-  void SetResourceListener(ResourceListener* listener) override;
   std::string Name() const override;
+  void SetResourceListener(ResourceListener* listener) override;
   absl::optional<ResourceUsageState> UsageState() const override;
   void ClearUsageState() override;
-  bool IsAdaptationUpAllowed(
-      const VideoStreamInputState& input_state,
-      const VideoSourceRestrictions& restrictions_before,
-      const VideoSourceRestrictions& restrictions_after,
-      rtc::scoped_refptr<Resource> reason_resource) const override;
-  void OnAdaptationApplied(
-      const VideoStreamInputState& input_state,
-      const VideoSourceRestrictions& restrictions_before,
-      const VideoSourceRestrictions& restrictions_after,
-      rtc::scoped_refptr<Resource> reason_resource) override;
 
  private:
-  rtc::CriticalSection lock_;
   const std::string name_;
-  TaskQueueBase* resource_adaptation_queue_;
-  bool is_adaptation_up_allowed_ RTC_GUARDED_BY(lock_);
-  size_t num_adaptations_applied_ RTC_GUARDED_BY(lock_);
-  absl::optional<ResourceUsageState> usage_state_
-      RTC_GUARDED_BY(resource_adaptation_queue_);
-  ResourceListener* listener_ RTC_GUARDED_BY(resource_adaptation_queue_);
+  ResourceListener* listener_;
+  absl::optional<ResourceUsageState> usage_state_;
 };
 
 }  // namespace webrtc
diff --git a/video/adaptation/encode_usage_resource.h b/video/adaptation/encode_usage_resource.h
index 6fcd0eb..257988f 100644
--- a/video/adaptation/encode_usage_resource.h
+++ b/video/adaptation/encode_usage_resource.h
@@ -17,7 +17,6 @@
 #include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
-#include "call/adaptation/resource.h"
 #include "rtc_base/ref_counted_object.h"
 #include "rtc_base/task_queue.h"
 #include "video/adaptation/overuse_frame_detector.h"
diff --git a/video/adaptation/quality_scaler_resource.h b/video/adaptation/quality_scaler_resource.h
index 43e99e7..372d0c9 100644
--- a/video/adaptation/quality_scaler_resource.h
+++ b/video/adaptation/quality_scaler_resource.h
@@ -19,7 +19,7 @@
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
 #include "api/video_codecs/video_encoder.h"
-#include "call/adaptation/resource.h"
+#include "call/adaptation/adaptation_listener.h"
 #include "call/adaptation/resource_adaptation_processor_interface.h"
 #include "modules/video_coding/utility/quality_scaler.h"
 #include "rtc_base/critical_section.h"
@@ -31,6 +31,7 @@
 
 // Handles interaction with the QualityScaler.
 class QualityScalerResource : public VideoStreamEncoderResource,
+                              public AdaptationListener,
                               public QualityScalerQpUsageHandlerInterface {
  public:
   static rtc::scoped_refptr<QualityScalerResource> Create();
@@ -60,7 +61,7 @@
       rtc::scoped_refptr<QualityScalerQpUsageHandlerCallbackInterface> callback)
       override;
 
-  // VideoStreamEncoderResource implementation.
+  // AdaptationListener implementation.
   void OnAdaptationApplied(
       const VideoStreamInputState& input_state,
       const VideoSourceRestrictions& restrictions_before,
diff --git a/video/adaptation/video_stream_encoder_resource.cc b/video/adaptation/video_stream_encoder_resource.cc
index db5a155..9a2db1f 100644
--- a/video/adaptation/video_stream_encoder_resource.cc
+++ b/video/adaptation/video_stream_encoder_resource.cc
@@ -75,20 +75,6 @@
   usage_state_ = absl::nullopt;
 }
 
-bool VideoStreamEncoderResource::IsAdaptationUpAllowed(
-    const VideoStreamInputState& input_state,
-    const VideoSourceRestrictions& restrictions_before,
-    const VideoSourceRestrictions& restrictions_after,
-    rtc::scoped_refptr<Resource> reason_resource) const {
-  return true;
-}
-
-void VideoStreamEncoderResource::OnAdaptationApplied(
-    const VideoStreamInputState& input_state,
-    const VideoSourceRestrictions& restrictions_before,
-    const VideoSourceRestrictions& restrictions_after,
-    rtc::scoped_refptr<Resource> reason_resource) {}
-
 void VideoStreamEncoderResource::OnResourceUsageStateMeasured(
     ResourceUsageState usage_state) {
   RTC_DCHECK_RUN_ON(resource_adaptation_queue());
diff --git a/video/adaptation/video_stream_encoder_resource.h b/video/adaptation/video_stream_encoder_resource.h
index fe66040..f561a63 100644
--- a/video/adaptation/video_stream_encoder_resource.h
+++ b/video/adaptation/video_stream_encoder_resource.h
@@ -16,6 +16,8 @@
 
 #include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
+#include "call/adaptation/adaptation_constraint.h"
+#include "call/adaptation/adaptation_listener.h"
 #include "call/adaptation/resource.h"
 #include "rtc_base/critical_section.h"
 #include "rtc_base/synchronization/sequence_checker.h"
@@ -30,24 +32,20 @@
   void RegisterEncoderTaskQueue(TaskQueueBase* encoder_queue);
 
   // Resource implementation.
-  void RegisterAdaptationTaskQueue(
-      TaskQueueBase* resource_adaptation_queue) override;
-  void UnregisterAdaptationTaskQueue() override;
-  void SetResourceListener(ResourceListener* listener) override;
   std::string Name() const override;
+  void SetResourceListener(ResourceListener* listener) override;
   absl::optional<ResourceUsageState> UsageState() const override;
   void ClearUsageState() override;
-  // Default implementations, may be overriden again by child classes.
-  bool IsAdaptationUpAllowed(
-      const VideoStreamInputState& input_state,
-      const VideoSourceRestrictions& restrictions_before,
-      const VideoSourceRestrictions& restrictions_after,
-      rtc::scoped_refptr<Resource> reason_resource) const override;
-  void OnAdaptationApplied(
-      const VideoStreamInputState& input_state,
-      const VideoSourceRestrictions& restrictions_before,
-      const VideoSourceRestrictions& restrictions_after,
-      rtc::scoped_refptr<Resource> reason_resource) override;
+
+  // Provides a pointer to the adaptation task queue. After this call, all
+  // methods defined in this interface, including
+  // UnregisterAdaptationTaskQueue() MUST be invoked on the adaptation task
+  // queue. Registering the adaptation task queue may, however, happen off the
+  // adaptation task queue.
+  void RegisterAdaptationTaskQueue(TaskQueueBase* resource_adaptation_queue);
+  // Signals that the adaptation task queue is no longer safe to use. No
+  // assumptions must be made as to whether or not tasks in-flight will run.
+  void UnregisterAdaptationTaskQueue();
 
  protected:
   explicit VideoStreamEncoderResource(std::string name);
diff --git a/video/adaptation/video_stream_encoder_resource_manager.cc b/video/adaptation/video_stream_encoder_resource_manager.cc
index c88c633..5b20e1f 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.cc
+++ b/video/adaptation/video_stream_encoder_resource_manager.cc
@@ -139,26 +139,30 @@
   int initial_framedrop_;
 };
 
-VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
-    PreventAdaptUpDueToActiveCounts(VideoStreamEncoderResourceManager* manager)
-    : rtc::RefCountedObject<VideoStreamEncoderResource>(
-          "PreventAdaptUpDueToActiveCounts"),
-      manager_(manager),
+VideoStreamEncoderResourceManager::ActiveCountsConstraint::
+    ActiveCountsConstraint(VideoStreamEncoderResourceManager* manager)
+    : manager_(manager),
+      resource_adaptation_queue_(nullptr),
       adaptation_processor_(nullptr) {}
 
-void VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
+void VideoStreamEncoderResourceManager::ActiveCountsConstraint::
+    SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue) {
+  resource_adaptation_queue_ = resource_adaptation_queue;
+}
+
+void VideoStreamEncoderResourceManager::ActiveCountsConstraint::
     SetAdaptationProcessor(
         ResourceAdaptationProcessorInterface* adaptation_processor) {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   adaptation_processor_ = adaptation_processor;
 }
 
-bool VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
+bool VideoStreamEncoderResourceManager::ActiveCountsConstraint::
     IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
                           const VideoSourceRestrictions& restrictions_before,
                           const VideoSourceRestrictions& restrictions_after,
                           rtc::scoped_refptr<Resource> reason_resource) const {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   RTC_DCHECK(adaptation_processor_);
   VideoAdaptationReason reason =
       manager_->GetReasonFromResource(reason_resource);
@@ -185,52 +189,47 @@
   }
 }
 
-VideoStreamEncoderResourceManager::
-    PreventIncreaseResolutionDueToBitrateResource::
-        PreventIncreaseResolutionDueToBitrateResource(
-            VideoStreamEncoderResourceManager* manager)
-    : rtc::RefCountedObject<VideoStreamEncoderResource>(
-          "PreventIncreaseResolutionDueToBitrateResource"),
-      manager_(manager),
+VideoStreamEncoderResourceManager::BitrateConstraint::BitrateConstraint(
+    VideoStreamEncoderResourceManager* manager)
+    : manager_(manager),
+      resource_adaptation_queue_(nullptr),
       encoder_settings_(absl::nullopt),
       encoder_target_bitrate_bps_(absl::nullopt) {}
 
-void VideoStreamEncoderResourceManager::
-    PreventIncreaseResolutionDueToBitrateResource::OnEncoderSettingsUpdated(
-        absl::optional<EncoderSettings> encoder_settings) {
-  RTC_DCHECK_RUN_ON(encoder_queue());
-  MaybePostTaskToResourceAdaptationQueue(
-      [this_ref =
-           rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
-               this),
-       encoder_settings] {
-        RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
+void VideoStreamEncoderResourceManager::BitrateConstraint::SetAdaptationQueue(
+    TaskQueueBase* resource_adaptation_queue) {
+  resource_adaptation_queue_ = resource_adaptation_queue;
+}
+
+void VideoStreamEncoderResourceManager::BitrateConstraint::
+    OnEncoderSettingsUpdated(absl::optional<EncoderSettings> encoder_settings) {
+  RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
+  resource_adaptation_queue_->PostTask(
+      ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
+                    encoder_settings] {
+        RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
         this_ref->encoder_settings_ = std::move(encoder_settings);
-      });
+      }));
 }
 
-void VideoStreamEncoderResourceManager::
-    PreventIncreaseResolutionDueToBitrateResource::
-        OnEncoderTargetBitrateUpdated(
-            absl::optional<uint32_t> encoder_target_bitrate_bps) {
-  RTC_DCHECK_RUN_ON(encoder_queue());
-  MaybePostTaskToResourceAdaptationQueue(
-      [this_ref =
-           rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
-               this),
-       encoder_target_bitrate_bps] {
-        RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
+void VideoStreamEncoderResourceManager::BitrateConstraint::
+    OnEncoderTargetBitrateUpdated(
+        absl::optional<uint32_t> encoder_target_bitrate_bps) {
+  RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
+  resource_adaptation_queue_->PostTask(
+      ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
+                    encoder_target_bitrate_bps] {
+        RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
         this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
-      });
+      }));
 }
 
-bool VideoStreamEncoderResourceManager::
-    PreventIncreaseResolutionDueToBitrateResource::IsAdaptationUpAllowed(
-        const VideoStreamInputState& input_state,
-        const VideoSourceRestrictions& restrictions_before,
-        const VideoSourceRestrictions& restrictions_after,
-        rtc::scoped_refptr<Resource> reason_resource) const {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+bool VideoStreamEncoderResourceManager::BitrateConstraint::
+    IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
+                          const VideoSourceRestrictions& restrictions_before,
+                          const VideoSourceRestrictions& restrictions_after,
+                          rtc::scoped_refptr<Resource> reason_resource) const {
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   VideoAdaptationReason reason =
       manager_->GetReasonFromResource(reason_resource);
   // If increasing resolution due to kQuality, make sure bitrate limits are not
@@ -259,39 +258,43 @@
   return true;
 }
 
-VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
-    PreventAdaptUpInBalancedResource(VideoStreamEncoderResourceManager* manager)
-    : rtc::RefCountedObject<VideoStreamEncoderResource>(
-          "PreventAdaptUpInBalancedResource"),
-      manager_(manager),
+VideoStreamEncoderResourceManager::BalancedConstraint::BalancedConstraint(
+    VideoStreamEncoderResourceManager* manager)
+    : manager_(manager),
+      resource_adaptation_queue_(nullptr),
       adaptation_processor_(nullptr),
       encoder_target_bitrate_bps_(absl::nullopt) {}
 
-void VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
+void VideoStreamEncoderResourceManager::BalancedConstraint::SetAdaptationQueue(
+    TaskQueueBase* resource_adaptation_queue) {
+  resource_adaptation_queue_ = resource_adaptation_queue;
+}
+
+void VideoStreamEncoderResourceManager::BalancedConstraint::
     SetAdaptationProcessor(
         ResourceAdaptationProcessorInterface* adaptation_processor) {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   adaptation_processor_ = adaptation_processor;
 }
 
-void VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
+void VideoStreamEncoderResourceManager::BalancedConstraint::
     OnEncoderTargetBitrateUpdated(
         absl::optional<uint32_t> encoder_target_bitrate_bps) {
-  RTC_DCHECK_RUN_ON(encoder_queue());
-  MaybePostTaskToResourceAdaptationQueue(
-      [this_ref = rtc::scoped_refptr<PreventAdaptUpInBalancedResource>(this),
-       encoder_target_bitrate_bps] {
-        RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
+  RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
+  resource_adaptation_queue_->PostTask(
+      ToQueuedTask([this_ref = rtc::scoped_refptr<BalancedConstraint>(this),
+                    encoder_target_bitrate_bps] {
+        RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
         this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
-      });
+      }));
 }
 
-bool VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
+bool VideoStreamEncoderResourceManager::BalancedConstraint::
     IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
                           const VideoSourceRestrictions& restrictions_before,
                           const VideoSourceRestrictions& restrictions_after,
                           rtc::scoped_refptr<Resource> reason_resource) const {
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   RTC_DCHECK(adaptation_processor_);
   VideoAdaptationReason reason =
       manager_->GetReasonFromResource(reason_resource);
@@ -325,12 +328,10 @@
     Clock* clock,
     bool experiment_cpu_load_estimator,
     std::unique_ptr<OveruseFrameDetector> overuse_detector)
-    : prevent_adapt_up_due_to_active_counts_(
-          new PreventAdaptUpDueToActiveCounts(this)),
-      prevent_increase_resolution_due_to_bitrate_resource_(
-          new PreventIncreaseResolutionDueToBitrateResource(this)),
-      prevent_adapt_up_in_balanced_resource_(
-          new PreventAdaptUpInBalancedResource(this)),
+    : active_counts_constraint_(
+          new rtc::RefCountedObject<ActiveCountsConstraint>(this)),
+      bitrate_constraint_(new rtc::RefCountedObject<BitrateConstraint>(this)),
+      balanced_constraint_(new rtc::RefCountedObject<BalancedConstraint>(this)),
       encode_usage_resource_(
           EncodeUsageResource::Create(std::move(overuse_detector))),
       quality_scaler_resource_(QualityScalerResource::Create()),
@@ -352,12 +353,6 @@
       encoder_settings_(absl::nullopt),
       active_counts_() {
   RTC_DCHECK(encoder_stats_observer_);
-  MapResourceToReason(prevent_adapt_up_due_to_active_counts_,
-                      VideoAdaptationReason::kQuality);
-  MapResourceToReason(prevent_increase_resolution_due_to_bitrate_resource_,
-                      VideoAdaptationReason::kQuality);
-  MapResourceToReason(prevent_adapt_up_in_balanced_resource_,
-                      VideoAdaptationReason::kQuality);
   MapResourceToReason(encode_usage_resource_, VideoAdaptationReason::kCpu);
   MapResourceToReason(quality_scaler_resource_,
                       VideoAdaptationReason::kQuality);
@@ -374,18 +369,10 @@
   RTC_DCHECK(resource_adaptation_queue);
   encoder_queue_ = encoder_queue;
   resource_adaptation_queue_ = resource_adaptation_queue;
-  prevent_adapt_up_due_to_active_counts_->RegisterEncoderTaskQueue(
-      encoder_queue_->Get());
-  prevent_adapt_up_due_to_active_counts_->RegisterAdaptationTaskQueue(
+  active_counts_constraint_->SetAdaptationQueue(
       resource_adaptation_queue_->Get());
-  prevent_increase_resolution_due_to_bitrate_resource_
-      ->RegisterEncoderTaskQueue(encoder_queue_->Get());
-  prevent_increase_resolution_due_to_bitrate_resource_
-      ->RegisterAdaptationTaskQueue(resource_adaptation_queue_->Get());
-  prevent_adapt_up_in_balanced_resource_->RegisterEncoderTaskQueue(
-      encoder_queue_->Get());
-  prevent_adapt_up_in_balanced_resource_->RegisterAdaptationTaskQueue(
-      resource_adaptation_queue_->Get());
+  bitrate_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
+  balanced_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
   encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
   encode_usage_resource_->RegisterAdaptationTaskQueue(
       resource_adaptation_queue_->Get());
@@ -398,10 +385,8 @@
     ResourceAdaptationProcessorInterface* adaptation_processor) {
   RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
   adaptation_processor_ = adaptation_processor;
-  prevent_adapt_up_due_to_active_counts_->SetAdaptationProcessor(
-      adaptation_processor);
-  prevent_adapt_up_in_balanced_resource_->SetAdaptationProcessor(
-      adaptation_processor);
+  active_counts_constraint_->SetAdaptationProcessor(adaptation_processor);
+  balanced_constraint_->SetAdaptationProcessor(adaptation_processor);
   quality_scaler_resource_->SetAdaptationProcessor(adaptation_processor);
 }
 
@@ -454,6 +439,16 @@
   return resources;
 }
 
+std::vector<AdaptationConstraint*>
+VideoStreamEncoderResourceManager::AdaptationConstraints() const {
+  return {active_counts_constraint_, bitrate_constraint_, balanced_constraint_};
+}
+
+std::vector<AdaptationListener*>
+VideoStreamEncoderResourceManager::AdaptationListeners() const {
+  return {quality_scaler_resource_};
+}
+
 rtc::scoped_refptr<QualityScalerResource>
 VideoStreamEncoderResourceManager::quality_scaler_resource_for_testing() {
   rtc::CritScope crit(&resource_lock_);
@@ -464,8 +459,7 @@
     EncoderSettings encoder_settings) {
   RTC_DCHECK_RUN_ON(encoder_queue_);
   encoder_settings_ = std::move(encoder_settings);
-  prevent_increase_resolution_due_to_bitrate_resource_
-      ->OnEncoderSettingsUpdated(encoder_settings_);
+  bitrate_constraint_->OnEncoderSettingsUpdated(encoder_settings_);
 
   quality_rampup_experiment_.SetMaxBitrate(
       LastInputFrameSizeOrDefault(),
@@ -478,9 +472,9 @@
   RTC_DCHECK_RUN_ON(encoder_queue_);
   if (!start_bitrate.IsZero()) {
     encoder_target_bitrate_bps_ = start_bitrate.bps();
-    prevent_increase_resolution_due_to_bitrate_resource_
-        ->OnEncoderTargetBitrateUpdated(encoder_target_bitrate_bps_);
-    prevent_adapt_up_in_balanced_resource_->OnEncoderTargetBitrateUpdated(
+    bitrate_constraint_->OnEncoderTargetBitrateUpdated(
+        encoder_target_bitrate_bps_);
+    balanced_constraint_->OnEncoderTargetBitrateUpdated(
         encoder_target_bitrate_bps_);
   }
   initial_frame_dropper_->SetStartBitrate(start_bitrate,
@@ -492,9 +486,9 @@
   RTC_DCHECK_RUN_ON(encoder_queue_);
   if (!target_bitrate.IsZero()) {
     encoder_target_bitrate_bps_ = target_bitrate.bps();
-    prevent_increase_resolution_due_to_bitrate_resource_
-        ->OnEncoderTargetBitrateUpdated(encoder_target_bitrate_bps_);
-    prevent_adapt_up_in_balanced_resource_->OnEncoderTargetBitrateUpdated(
+    bitrate_constraint_->OnEncoderTargetBitrateUpdated(
+        encoder_target_bitrate_bps_);
+    balanced_constraint_->OnEncoderTargetBitrateUpdated(
         encoder_target_bitrate_bps_);
   }
   initial_frame_dropper_->SetTargetBitrate(target_bitrate,
diff --git a/video/adaptation/video_stream_encoder_resource_manager.h b/video/adaptation/video_stream_encoder_resource_manager.h
index 4563b74..ef42636 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.h
+++ b/video/adaptation/video_stream_encoder_resource_manager.h
@@ -22,6 +22,7 @@
 #include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "api/scoped_refptr.h"
+#include "api/task_queue/task_queue_base.h"
 #include "api/video/video_adaptation_counters.h"
 #include "api/video/video_adaptation_reason.h"
 #include "api/video/video_frame.h"
@@ -37,6 +38,7 @@
 #include "rtc_base/critical_section.h"
 #include "rtc_base/experiments/quality_rampup_experiment.h"
 #include "rtc_base/experiments/quality_scaler_settings.h"
+#include "rtc_base/ref_count.h"
 #include "rtc_base/strings/string_builder.h"
 #include "rtc_base/task_queue.h"
 #include "system_wrappers/include/clock.h"
@@ -62,7 +64,7 @@
 // The manager is also involved with various mitigations not part of the
 // ResourceAdaptationProcessor code such as the inital frame dropping.
 class VideoStreamEncoderResourceManager
-    : public ResourceAdaptationProcessorListener {
+    : public VideoSourceRestrictionsListener {
  public:
   VideoStreamEncoderResourceManager(
       VideoStreamInputStateProvider* input_state_provider,
@@ -117,13 +119,15 @@
   void MapResourceToReason(rtc::scoped_refptr<Resource> resource,
                            VideoAdaptationReason reason);
   std::vector<rtc::scoped_refptr<Resource>> MappedResources() const;
+  std::vector<AdaptationConstraint*> AdaptationConstraints() const;
+  std::vector<AdaptationListener*> AdaptationListeners() const;
   rtc::scoped_refptr<QualityScalerResource>
   quality_scaler_resource_for_testing();
   // If true, the VideoStreamEncoder should eexecute its logic to maybe drop
   // frames baseed on size and bitrate.
   bool DropInitialFrames() const;
 
-  // ResourceAdaptationProcessorListener implementation.
+  // VideoSourceRestrictionsListener implementation.
   // Updates |video_source_restrictions_| and |active_counts_|.
   void OnVideoSourceRestrictionsUpdated(
       VideoSourceRestrictions restrictions,
@@ -173,22 +177,22 @@
   void ResetActiveCounts();
   std::string ActiveCountsToString() const;
 
-  // TODO(hbos): Consider moving all of the manager's resources into separate
-  // files for testability.
+  // TODO(hbos): Add tests for manager's constraints.
 
   // Does not trigger adaptations, only prevents adapting up based on
   // |active_counts_|.
-  class PreventAdaptUpDueToActiveCounts final
-      : public rtc::RefCountedObject<VideoStreamEncoderResource> {
+  class ActiveCountsConstraint : public rtc::RefCountInterface,
+                                 public AdaptationConstraint {
    public:
-    explicit PreventAdaptUpDueToActiveCounts(
-        VideoStreamEncoderResourceManager* manager);
-    ~PreventAdaptUpDueToActiveCounts() override = default;
+    explicit ActiveCountsConstraint(VideoStreamEncoderResourceManager* manager);
+    ~ActiveCountsConstraint() override = default;
 
+    void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
     void SetAdaptationProcessor(
         ResourceAdaptationProcessorInterface* adaptation_processor);
 
-    // Resource overrides.
+    // AdaptationConstraint implementation.
+    std::string Name() const override { return "ActiveCountsConstraint"; }
     bool IsAdaptationUpAllowed(
         const VideoStreamInputState& input_state,
         const VideoSourceRestrictions& restrictions_before,
@@ -199,24 +203,26 @@
     // The |manager_| must be alive as long as this resource is added to the
     // ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
     VideoStreamEncoderResourceManager* const manager_;
+    TaskQueueBase* resource_adaptation_queue_;
     ResourceAdaptationProcessorInterface* adaptation_processor_
-        RTC_GUARDED_BY(resource_adaptation_queue());
+        RTC_GUARDED_BY(resource_adaptation_queue_);
   };
 
   // Does not trigger adaptations, only prevents adapting up resolution.
-  class PreventIncreaseResolutionDueToBitrateResource final
-      : public rtc::RefCountedObject<VideoStreamEncoderResource> {
+  class BitrateConstraint : public rtc::RefCountInterface,
+                            public AdaptationConstraint {
    public:
-    explicit PreventIncreaseResolutionDueToBitrateResource(
-        VideoStreamEncoderResourceManager* manager);
-    ~PreventIncreaseResolutionDueToBitrateResource() override = default;
+    explicit BitrateConstraint(VideoStreamEncoderResourceManager* manager);
+    ~BitrateConstraint() override = default;
 
+    void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
     void OnEncoderSettingsUpdated(
         absl::optional<EncoderSettings> encoder_settings);
     void OnEncoderTargetBitrateUpdated(
         absl::optional<uint32_t> encoder_target_bitrate_bps);
 
-    // Resource overrides.
+    // AdaptationConstraint implementation.
+    std::string Name() const override { return "BitrateConstraint"; }
     bool IsAdaptationUpAllowed(
         const VideoStreamInputState& input_state,
         const VideoSourceRestrictions& restrictions_before,
@@ -227,26 +233,28 @@
     // The |manager_| must be alive as long as this resource is added to the
     // ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
     VideoStreamEncoderResourceManager* const manager_;
+    TaskQueueBase* resource_adaptation_queue_;
     absl::optional<EncoderSettings> encoder_settings_
-        RTC_GUARDED_BY(resource_adaptation_queue());
+        RTC_GUARDED_BY(resource_adaptation_queue_);
     absl::optional<uint32_t> encoder_target_bitrate_bps_
-        RTC_GUARDED_BY(resource_adaptation_queue());
+        RTC_GUARDED_BY(resource_adaptation_queue_);
   };
 
   // Does not trigger adaptations, only prevents adapting up in BALANCED.
-  class PreventAdaptUpInBalancedResource final
-      : public rtc::RefCountedObject<VideoStreamEncoderResource> {
+  class BalancedConstraint : public rtc::RefCountInterface,
+                             public AdaptationConstraint {
    public:
-    explicit PreventAdaptUpInBalancedResource(
-        VideoStreamEncoderResourceManager* manager);
-    ~PreventAdaptUpInBalancedResource() override = default;
+    explicit BalancedConstraint(VideoStreamEncoderResourceManager* manager);
+    ~BalancedConstraint() override = default;
 
+    void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
     void SetAdaptationProcessor(
         ResourceAdaptationProcessorInterface* adaptation_processor);
     void OnEncoderTargetBitrateUpdated(
         absl::optional<uint32_t> encoder_target_bitrate_bps);
 
-    // Resource overrides.
+    // AdaptationConstraint implementation.
+    std::string Name() const override { return "BalancedConstraint"; }
     bool IsAdaptationUpAllowed(
         const VideoStreamInputState& input_state,
         const VideoSourceRestrictions& restrictions_before,
@@ -257,18 +265,16 @@
     // The |manager_| must be alive as long as this resource is added to the
     // ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
     VideoStreamEncoderResourceManager* const manager_;
+    TaskQueueBase* resource_adaptation_queue_;
     ResourceAdaptationProcessorInterface* adaptation_processor_
-        RTC_GUARDED_BY(resource_adaptation_queue());
+        RTC_GUARDED_BY(resource_adaptation_queue_);
     absl::optional<uint32_t> encoder_target_bitrate_bps_
-        RTC_GUARDED_BY(resource_adaptation_queue());
+        RTC_GUARDED_BY(resource_adaptation_queue_);
   };
 
-  const rtc::scoped_refptr<PreventAdaptUpDueToActiveCounts>
-      prevent_adapt_up_due_to_active_counts_;
-  const rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>
-      prevent_increase_resolution_due_to_bitrate_resource_;
-  const rtc::scoped_refptr<PreventAdaptUpInBalancedResource>
-      prevent_adapt_up_in_balanced_resource_;
+  const rtc::scoped_refptr<ActiveCountsConstraint> active_counts_constraint_;
+  const rtc::scoped_refptr<BitrateConstraint> bitrate_constraint_;
+  const rtc::scoped_refptr<BalancedConstraint> balanced_constraint_;
   const rtc::scoped_refptr<EncodeUsageResource> encode_usage_resource_;
   const rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource_;
 
@@ -321,7 +327,7 @@
   // TODO(https://crbug.com/webrtc/11542): When we have an adaptation queue,
   // guard the activec counts by it instead. The |encoder_stats_observer_| is
   // thread-safe anyway, and active counts are used by
-  // PreventAdaptUpDueToActiveCounts to make decisions.
+  // ActiveCountsConstraint to make decisions.
   std::unordered_map<VideoAdaptationReason, VideoAdaptationCounters>
       active_counts_ RTC_GUARDED_BY(resource_adaptation_queue_);
 };
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 95c6055..7014138 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -260,6 +260,8 @@
           std::make_unique<ResourceAdaptationProcessor>(
               &input_state_provider_,
               encoder_stats_observer)),
+      adaptation_constraints_(),
+      adaptation_listeners_(),
       stream_resource_manager_(&input_state_provider_,
                                encoder_stats_observer,
                                clock_,
@@ -285,12 +287,22 @@
     resource_adaptation_processor_->InitializeOnResourceAdaptationQueue();
     stream_resource_manager_.SetAdaptationProcessor(
         resource_adaptation_processor_.get());
-    resource_adaptation_processor_->AddAdaptationListener(
+    resource_adaptation_processor_->AddRestrictionsListener(
         &stream_resource_manager_);
-    resource_adaptation_processor_->AddAdaptationListener(this);
+    resource_adaptation_processor_->AddRestrictionsListener(this);
+
     // Add the stream resource manager's resources to the processor.
-    for (Resource* resource : stream_resource_manager_.MappedResources())
+    adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
+    adaptation_listeners_ = stream_resource_manager_.AdaptationListeners();
+    for (auto& resource : stream_resource_manager_.MappedResources()) {
       resource_adaptation_processor_->AddResource(resource);
+    }
+    for (auto* constraint : adaptation_constraints_) {
+      resource_adaptation_processor_->AddAdaptationConstraint(constraint);
+    }
+    for (auto* listener : adaptation_listeners_) {
+      resource_adaptation_processor_->AddAdaptationListener(listener);
+    }
     initialize_processor_event.Set();
   });
   initialize_processor_event.Wait(rtc::Event::kForever);
@@ -312,11 +324,17 @@
     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
     if (resource_adaptation_processor_) {
       resource_adaptation_processor_->StopResourceAdaptation();
-      for (Resource* resource : stream_resource_manager_.MappedResources()) {
+      for (auto& resource : stream_resource_manager_.MappedResources()) {
         resource_adaptation_processor_->RemoveResource(resource);
       }
-      resource_adaptation_processor_->RemoveAdaptationListener(this);
-      resource_adaptation_processor_->RemoveAdaptationListener(
+      for (auto* constraint : adaptation_constraints_) {
+        resource_adaptation_processor_->RemoveAdaptationConstraint(constraint);
+      }
+      for (auto* listener : adaptation_listeners_) {
+        resource_adaptation_processor_->RemoveAdaptationListener(listener);
+      }
+      resource_adaptation_processor_->RemoveRestrictionsListener(this);
+      resource_adaptation_processor_->RemoveRestrictionsListener(
           &stream_resource_manager_);
       stream_resource_manager_.SetAdaptationProcessor(nullptr);
       resource_adaptation_processor_.reset();
@@ -1978,7 +1996,8 @@
   });
   map_resource_event.Wait(rtc::Event::kForever);
 
-  resource_adaptation_queue_.PostTask([this, resource] {
+  rtc::Event add_resource_event;
+  resource_adaptation_queue_.PostTask([this, resource, &add_resource_event] {
     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
     if (!resource_adaptation_processor_) {
       // The VideoStreamEncoder was stopped and the processor destroyed before
@@ -1986,7 +2005,44 @@
       return;
     }
     resource_adaptation_processor_->AddResource(resource);
+    add_resource_event.Set();
   });
+  add_resource_event.Wait(rtc::Event::kForever);
+}
+
+void VideoStreamEncoder::InjectAdaptationConstraint(
+    AdaptationConstraint* adaptation_constraint) {
+  rtc::Event event;
+  resource_adaptation_queue_.PostTask([this, adaptation_constraint, &event] {
+    RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
+    if (!resource_adaptation_processor_) {
+      // The VideoStreamEncoder was stopped and the processor destroyed before
+      // this task had a chance to execute. No action needed.
+      return;
+    }
+    adaptation_constraints_.push_back(adaptation_constraint);
+    resource_adaptation_processor_->AddAdaptationConstraint(
+        adaptation_constraint);
+    event.Set();
+  });
+  event.Wait(rtc::Event::kForever);
+}
+
+void VideoStreamEncoder::InjectAdaptationListener(
+    AdaptationListener* adaptation_listener) {
+  rtc::Event event;
+  resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
+    RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
+    if (!resource_adaptation_processor_) {
+      // The VideoStreamEncoder was stopped and the processor destroyed before
+      // this task had a chance to execute. No action needed.
+      return;
+    }
+    adaptation_listeners_.push_back(adaptation_listener);
+    resource_adaptation_processor_->AddAdaptationListener(adaptation_listener);
+    event.Set();
+  });
+  event.Wait(rtc::Event::kForever);
 }
 
 rtc::scoped_refptr<QualityScalerResource>
@@ -1995,26 +2051,27 @@
   return stream_resource_manager_.quality_scaler_resource_for_testing();
 }
 
-void VideoStreamEncoder::AddAdaptationListenerForTesting(
-    ResourceAdaptationProcessorListener* adaptation_listener) {
+void VideoStreamEncoder::AddRestrictionsListenerForTesting(
+    VideoSourceRestrictionsListener* restrictions_listener) {
   rtc::Event event;
-  resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
+  resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
     RTC_DCHECK(resource_adaptation_processor_);
-    resource_adaptation_processor_->AddAdaptationListener(adaptation_listener);
+    resource_adaptation_processor_->AddRestrictionsListener(
+        restrictions_listener);
     event.Set();
   });
   event.Wait(rtc::Event::kForever);
 }
 
-void VideoStreamEncoder::RemoveAdaptationListenerForTesting(
-    ResourceAdaptationProcessorListener* adaptation_listener) {
+void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
+    VideoSourceRestrictionsListener* restrictions_listener) {
   rtc::Event event;
-  resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
+  resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
     RTC_DCHECK(resource_adaptation_processor_);
-    resource_adaptation_processor_->RemoveAdaptationListener(
-        adaptation_listener);
+    resource_adaptation_processor_->RemoveRestrictionsListener(
+        restrictions_listener);
     event.Set();
   });
   event.Wait(rtc::Event::kForever);
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 193aa1e..83b6911 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -26,6 +26,9 @@
 #include "api/video/video_stream_encoder_settings.h"
 #include "api/video_codecs/video_codec.h"
 #include "api/video_codecs/video_encoder.h"
+#include "call/adaptation/adaptation_constraint.h"
+#include "call/adaptation/adaptation_listener.h"
+#include "call/adaptation/resource.h"
 #include "call/adaptation/resource_adaptation_processor_interface.h"
 #include "call/adaptation/video_source_restrictions.h"
 #include "call/adaptation/video_stream_input_state_provider.h"
@@ -44,6 +47,7 @@
 #include "video/encoder_bitrate_adjuster.h"
 #include "video/frame_encode_metadata_writer.h"
 #include "video/video_source_sink_controller.h"
+
 namespace webrtc {
 
 // VideoStreamEncoder represent a video encoder that accepts raw video frames as
@@ -56,7 +60,7 @@
 //  Call Stop() when done.
 class VideoStreamEncoder : public VideoStreamEncoderInterface,
                            private EncodedImageCallback,
-                           public ResourceAdaptationProcessorListener {
+                           public VideoSourceRestrictionsListener {
  public:
   VideoStreamEncoder(Clock* clock,
                      uint32_t number_of_cores,
@@ -118,16 +122,17 @@
   // Used for injected test resources.
   // TODO(eshr): Move all adaptation tests out of VideoStreamEncoder tests.
   void InjectAdaptationResource(rtc::scoped_refptr<Resource> resource,
-                                VideoAdaptationReason reason)
-      RTC_RUN_ON(&encoder_queue_);
+                                VideoAdaptationReason reason);
+  void InjectAdaptationConstraint(AdaptationConstraint* adaptation_constraint);
+  void InjectAdaptationListener(AdaptationListener* adaptation_listener);
 
   rtc::scoped_refptr<QualityScalerResource>
   quality_scaler_resource_for_testing();
 
-  void AddAdaptationListenerForTesting(
-      ResourceAdaptationProcessorListener* adaptation_listener);
-  void RemoveAdaptationListenerForTesting(
-      ResourceAdaptationProcessorListener* adaptation_listener);
+  void AddRestrictionsListenerForTesting(
+      VideoSourceRestrictionsListener* restrictions_listener);
+  void RemoveRestrictionsListenerForTesting(
+      VideoSourceRestrictionsListener* restrictions_listener);
 
  private:
   class VideoFrameInfo {
@@ -406,6 +411,10 @@
   std::unique_ptr<ResourceAdaptationProcessorInterface>
       resource_adaptation_processor_
           RTC_GUARDED_BY(&resource_adaptation_queue_);
+  std::vector<AdaptationConstraint*> adaptation_constraints_
+      RTC_GUARDED_BY(&resource_adaptation_queue_);
+  std::vector<AdaptationListener*> adaptation_listeners_
+      RTC_GUARDED_BY(&resource_adaptation_queue_);
   // Handles input, output and stats reporting related to VideoStreamEncoder
   // specific resources, such as "encode usage percent" measurements and "QP
   // scaling". Also involved with various mitigations such as inital frame
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 005118d..6ce6265 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -26,6 +26,8 @@
 #include "api/video_codecs/video_encoder.h"
 #include "api/video_codecs/vp8_temporal_layers.h"
 #include "api/video_codecs/vp8_temporal_layers_factory.h"
+#include "call/adaptation/test/fake_adaptation_constraint.h"
+#include "call/adaptation/test/fake_adaptation_listener.h"
 #include "call/adaptation/test/fake_resource.h"
 #include "common_video/h264/h264_common.h"
 #include "common_video/include/video_frame_buffer.h"
@@ -186,12 +188,12 @@
   absl::optional<bool> clear_qp_samples_result_;
 };
 
-class VideoSourceRestrictionsUpdatedListener
-    : public ResourceAdaptationProcessorListener {
+class FakeVideoSourceRestrictionsListener
+    : public VideoSourceRestrictionsListener {
  public:
-  VideoSourceRestrictionsUpdatedListener()
+  FakeVideoSourceRestrictionsListener()
       : was_restrictions_updated_(false), restrictions_updated_event_() {}
-  ~VideoSourceRestrictionsUpdatedListener() override {
+  ~FakeVideoSourceRestrictionsListener() override {
     RTC_DCHECK(was_restrictions_updated_);
   }
 
@@ -199,7 +201,7 @@
     return &restrictions_updated_event_;
   }
 
-  // ResourceAdaptationProcessorListener implementation.
+  // VideoSourceRestrictionsListener implementation.
   void OnVideoSourceRestrictionsUpdated(
       VideoSourceRestrictions restrictions,
       const VideoAdaptationCounters& adaptation_counters,
@@ -317,24 +319,24 @@
                                    new CpuOveruseDetectorProxy(stats_proxy)),
                            task_queue_factory),
         fake_cpu_resource_(FakeResource::Create("FakeResource[CPU]")),
-        fake_quality_resource_(FakeResource::Create("FakeResource[QP]")) {
-    fake_cpu_resource_->RegisterAdaptationTaskQueue(
-        resource_adaptation_queue()->Get());
-    fake_quality_resource_->RegisterAdaptationTaskQueue(
-        resource_adaptation_queue()->Get());
+        fake_quality_resource_(FakeResource::Create("FakeResource[QP]")),
+        fake_adaptation_constraint_("FakeAdaptationConstraint"),
+        fake_adaptation_listener_() {
     InjectAdaptationResource(fake_quality_resource_,
                              VideoAdaptationReason::kQuality);
     InjectAdaptationResource(fake_cpu_resource_, VideoAdaptationReason::kCpu);
+    InjectAdaptationConstraint(&fake_adaptation_constraint_);
+    InjectAdaptationListener(&fake_adaptation_listener_);
   }
 
   void SetSourceAndWaitForRestrictionsUpdated(
       rtc::VideoSourceInterface<VideoFrame>* source,
       const DegradationPreference& degradation_preference) {
-    VideoSourceRestrictionsUpdatedListener listener;
-    AddAdaptationListenerForTesting(&listener);
+    FakeVideoSourceRestrictionsListener listener;
+    AddRestrictionsListenerForTesting(&listener);
     SetSource(source, degradation_preference);
     listener.restrictions_updated_event()->Wait(5000);
-    RemoveAdaptationListenerForTesting(&listener);
+    RemoveRestrictionsListenerForTesting(&listener);
   }
 
   void SetSourceAndWaitForFramerateUpdated(
@@ -379,7 +381,7 @@
   void TriggerCpuOveruse() {
     rtc::Event event;
     resource_adaptation_queue()->PostTask([this, &event] {
-      fake_cpu_resource_->set_usage_state(ResourceUsageState::kOveruse);
+      fake_cpu_resource_->SetUsageState(ResourceUsageState::kOveruse);
       event.Set();
     });
     ASSERT_TRUE(event.Wait(5000));
@@ -387,7 +389,7 @@
   void TriggerCpuUnderuse() {
     rtc::Event event;
     resource_adaptation_queue()->PostTask([this, &event] {
-      fake_cpu_resource_->set_usage_state(ResourceUsageState::kUnderuse);
+      fake_cpu_resource_->SetUsageState(ResourceUsageState::kUnderuse);
       event.Set();
     });
     ASSERT_TRUE(event.Wait(5000));
@@ -397,7 +399,7 @@
   void TriggerQualityLow() {
     rtc::Event event;
     resource_adaptation_queue()->PostTask([this, &event] {
-      fake_quality_resource_->set_usage_state(ResourceUsageState::kOveruse);
+      fake_quality_resource_->SetUsageState(ResourceUsageState::kOveruse);
       event.Set();
     });
     ASSERT_TRUE(event.Wait(5000));
@@ -405,7 +407,7 @@
   void TriggerQualityHigh() {
     rtc::Event event;
     resource_adaptation_queue()->PostTask([this, &event] {
-      fake_quality_resource_->set_usage_state(ResourceUsageState::kUnderuse);
+      fake_quality_resource_->SetUsageState(ResourceUsageState::kUnderuse);
       event.Set();
     });
     ASSERT_TRUE(event.Wait(5000));
@@ -430,6 +432,8 @@
   CpuOveruseDetectorProxy* overuse_detector_proxy_;
   rtc::scoped_refptr<FakeResource> fake_cpu_resource_;
   rtc::scoped_refptr<FakeResource> fake_quality_resource_;
+  FakeAdaptationConstraint fake_adaptation_constraint_;
+  FakeAdaptationListener fake_adaptation_listener_;
 };
 
 class VideoStreamFactory