1 /* 2 * Copyright 2020 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "call/adaptation/broadcast_resource_listener.h" 12 13 #include <algorithm> 14 #include <string> 15 #include <utility> 16 17 #include "rtc_base/checks.h" 18 #include "rtc_base/ref_counted_object.h" 19 #include "rtc_base/synchronization/mutex.h" 20 21 namespace webrtc { 22 23 // The AdapterResource redirects resource usage measurements from its parent to 24 // a single ResourceListener. 25 class BroadcastResourceListener::AdapterResource : public Resource { 26 public: AdapterResource(std::string name)27 explicit AdapterResource(std::string name) : name_(std::move(name)) {} ~AdapterResource()28 ~AdapterResource() override { RTC_DCHECK(!listener_); } 29 30 // The parent is letting us know we have a usage neasurement. OnResourceUsageStateMeasured(ResourceUsageState usage_state)31 void OnResourceUsageStateMeasured(ResourceUsageState usage_state) { 32 MutexLock lock(&lock_); 33 if (!listener_) 34 return; 35 listener_->OnResourceUsageStateMeasured(this, usage_state); 36 } 37 38 // Resource implementation. Name() const39 std::string Name() const override { return name_; } SetResourceListener(ResourceListener * listener)40 void SetResourceListener(ResourceListener* listener) override { 41 MutexLock lock(&lock_); 42 RTC_DCHECK(!listener_ || !listener); 43 listener_ = listener; 44 } 45 46 private: 47 const std::string name_; 48 Mutex lock_; 49 ResourceListener* listener_ RTC_GUARDED_BY(lock_) = nullptr; 50 }; 51 BroadcastResourceListener(rtc::scoped_refptr<Resource> source_resource)52BroadcastResourceListener::BroadcastResourceListener( 53 rtc::scoped_refptr<Resource> source_resource) 54 : source_resource_(source_resource), is_listening_(false) { 55 RTC_DCHECK(source_resource_); 56 } 57 ~BroadcastResourceListener()58BroadcastResourceListener::~BroadcastResourceListener() { 59 RTC_DCHECK(!is_listening_); 60 } 61 SourceResource() const62rtc::scoped_refptr<Resource> BroadcastResourceListener::SourceResource() const { 63 return source_resource_; 64 } 65 StartListening()66void BroadcastResourceListener::StartListening() { 67 MutexLock lock(&lock_); 68 RTC_DCHECK(!is_listening_); 69 source_resource_->SetResourceListener(this); 70 is_listening_ = true; 71 } 72 StopListening()73void BroadcastResourceListener::StopListening() { 74 MutexLock lock(&lock_); 75 RTC_DCHECK(is_listening_); 76 RTC_DCHECK(adapters_.empty()); 77 source_resource_->SetResourceListener(nullptr); 78 is_listening_ = false; 79 } 80 81 rtc::scoped_refptr<Resource> CreateAdapterResource()82BroadcastResourceListener::CreateAdapterResource() { 83 MutexLock lock(&lock_); 84 RTC_DCHECK(is_listening_); 85 rtc::scoped_refptr<AdapterResource> adapter = 86 new rtc::RefCountedObject<AdapterResource>(source_resource_->Name() + 87 "Adapter"); 88 adapters_.push_back(adapter); 89 return adapter; 90 } 91 RemoveAdapterResource(rtc::scoped_refptr<Resource> resource)92void BroadcastResourceListener::RemoveAdapterResource( 93 rtc::scoped_refptr<Resource> resource) { 94 MutexLock lock(&lock_); 95 auto it = std::find(adapters_.begin(), adapters_.end(), resource); 96 RTC_DCHECK(it != adapters_.end()); 97 adapters_.erase(it); 98 } 99 100 std::vector<rtc::scoped_refptr<Resource>> GetAdapterResources()101BroadcastResourceListener::GetAdapterResources() { 102 std::vector<rtc::scoped_refptr<Resource>> resources; 103 MutexLock lock(&lock_); 104 for (const auto& adapter : adapters_) { 105 resources.push_back(adapter); 106 } 107 return resources; 108 } 109 OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,ResourceUsageState usage_state)110void BroadcastResourceListener::OnResourceUsageStateMeasured( 111 rtc::scoped_refptr<Resource> resource, 112 ResourceUsageState usage_state) { 113 RTC_DCHECK_EQ(resource, source_resource_); 114 MutexLock lock(&lock_); 115 for (const auto& adapter : adapters_) { 116 adapter->OnResourceUsageStateMeasured(usage_state); 117 } 118 } 119 120 } // namespace webrtc 121