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 "absl/strings/string_view.h" 18 #include "api/make_ref_counted.h" 19 #include "rtc_base/checks.h" 20 #include "rtc_base/synchronization/mutex.h" 21 22 namespace webrtc { 23 24 // The AdapterResource redirects resource usage measurements from its parent to 25 // a single ResourceListener. 26 class BroadcastResourceListener::AdapterResource : public Resource { 27 public: AdapterResource(absl::string_view name)28 explicit AdapterResource(absl::string_view name) : name_(std::move(name)) {} ~AdapterResource()29 ~AdapterResource() override { RTC_DCHECK(!listener_); } 30 31 // The parent is letting us know we have a usage neasurement. OnResourceUsageStateMeasured(ResourceUsageState usage_state)32 void OnResourceUsageStateMeasured(ResourceUsageState usage_state) { 33 MutexLock lock(&lock_); 34 if (!listener_) 35 return; 36 listener_->OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource>(this), 37 usage_state); 38 } 39 40 // Resource implementation. Name() const41 std::string Name() const override { return name_; } SetResourceListener(ResourceListener * listener)42 void SetResourceListener(ResourceListener* listener) override { 43 MutexLock lock(&lock_); 44 RTC_DCHECK(!listener_ || !listener); 45 listener_ = listener; 46 } 47 48 private: 49 const std::string name_; 50 Mutex lock_; 51 ResourceListener* listener_ RTC_GUARDED_BY(lock_) = nullptr; 52 }; 53 BroadcastResourceListener(rtc::scoped_refptr<Resource> source_resource)54BroadcastResourceListener::BroadcastResourceListener( 55 rtc::scoped_refptr<Resource> source_resource) 56 : source_resource_(source_resource), is_listening_(false) { 57 RTC_DCHECK(source_resource_); 58 } 59 ~BroadcastResourceListener()60BroadcastResourceListener::~BroadcastResourceListener() { 61 RTC_DCHECK(!is_listening_); 62 } 63 SourceResource() const64rtc::scoped_refptr<Resource> BroadcastResourceListener::SourceResource() const { 65 return source_resource_; 66 } 67 StartListening()68void BroadcastResourceListener::StartListening() { 69 MutexLock lock(&lock_); 70 RTC_DCHECK(!is_listening_); 71 source_resource_->SetResourceListener(this); 72 is_listening_ = true; 73 } 74 StopListening()75void BroadcastResourceListener::StopListening() { 76 MutexLock lock(&lock_); 77 RTC_DCHECK(is_listening_); 78 RTC_DCHECK(adapters_.empty()); 79 source_resource_->SetResourceListener(nullptr); 80 is_listening_ = false; 81 } 82 83 rtc::scoped_refptr<Resource> CreateAdapterResource()84BroadcastResourceListener::CreateAdapterResource() { 85 MutexLock lock(&lock_); 86 RTC_DCHECK(is_listening_); 87 rtc::scoped_refptr<AdapterResource> adapter = 88 rtc::make_ref_counted<AdapterResource>(source_resource_->Name() + 89 "Adapter"); 90 adapters_.push_back(adapter); 91 return adapter; 92 } 93 RemoveAdapterResource(rtc::scoped_refptr<Resource> resource)94void BroadcastResourceListener::RemoveAdapterResource( 95 rtc::scoped_refptr<Resource> resource) { 96 MutexLock lock(&lock_); 97 auto it = std::find(adapters_.begin(), adapters_.end(), resource); 98 RTC_DCHECK(it != adapters_.end()); 99 adapters_.erase(it); 100 } 101 102 std::vector<rtc::scoped_refptr<Resource>> GetAdapterResources()103BroadcastResourceListener::GetAdapterResources() { 104 std::vector<rtc::scoped_refptr<Resource>> resources; 105 MutexLock lock(&lock_); 106 for (const auto& adapter : adapters_) { 107 resources.push_back(adapter); 108 } 109 return resources; 110 } 111 OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,ResourceUsageState usage_state)112void BroadcastResourceListener::OnResourceUsageStateMeasured( 113 rtc::scoped_refptr<Resource> resource, 114 ResourceUsageState usage_state) { 115 RTC_DCHECK_EQ(resource, source_resource_); 116 MutexLock lock(&lock_); 117 for (const auto& adapter : adapters_) { 118 adapter->OnResourceUsageStateMeasured(usage_state); 119 } 120 } 121 122 } // namespace webrtc 123