Commit 8afd0b71 authored by Henrik Boström's avatar Henrik Boström Committed by Commit Bot

[Adaptation] Make use of ThermalResource in WebRTC.

If we receive a thermal signal we lazily instantiate the
ThermalResource and inject it into the webrtc::PeerConnection.
The ThermalResource is wired to respond to new thermal measurements.

This will make the WebRTC video pipeline be able to react to overuse
or underuse due to thermal signals.

The ThermalResource is only used if the corresponding base::Feature is
enabled, which is DISABLED by default. Both code paths are tested.

Bug: chromium:1094844
Change-Id: I9f47c1f4f9bc98349b328d71f0eb71cc4c398444
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2247837
Commit-Queue: Henrik Boström <hbos@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781223}
parent 3a46c767
......@@ -215,6 +215,8 @@ jumbo_source_set("modules_testing") {
"peerconnection/adapters/test/mock_p2p_quic_transport.h",
"peerconnection/adapters/test/mock_p2p_quic_transport_delegate.h",
"peerconnection/adapters/test/mock_p2p_quic_transport_factory.h",
"peerconnection/testing/fake_resource_listener.cc",
"peerconnection/testing/fake_resource_listener.h",
"peerconnection/testing/internals_rtc_certificate.cc",
"peerconnection/testing/internals_rtc_certificate.h",
"peerconnection/testing/internals_rtc_peer_connection.cc",
......
......@@ -12,6 +12,7 @@
#include "base/notreached.h"
#include "base/optional.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc/api/dtls_transport_interface.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
#include "third_party/webrtc/api/sctp_transport_interface.h"
......@@ -359,6 +360,15 @@ class MockPeerConnectionImpl : public webrtc::DummyPeerConnection {
static const char kDummyOffer[];
static const char kDummyAnswer[];
void AddAdaptationResource(
rtc::scoped_refptr<webrtc::Resource> resource) override {
adaptation_resources_.push_back(resource);
}
Vector<rtc::scoped_refptr<webrtc::Resource>> adaptation_resources() const {
return adaptation_resources_;
}
protected:
~MockPeerConnectionImpl() override;
......@@ -385,6 +395,7 @@ class MockPeerConnectionImpl : public webrtc::DummyPeerConnection {
webrtc::RTCErrorType setconfiguration_error_type_ =
webrtc::RTCErrorType::NONE;
rtc::scoped_refptr<webrtc::RTCStatsReport> stats_report_;
Vector<rtc::scoped_refptr<webrtc::Resource>> adaptation_resources_;
DISALLOW_COPY_AND_ASSIGN(MockPeerConnectionImpl);
};
......
......@@ -2085,6 +2085,19 @@ void RTCPeerConnectionHandler::CloseClientPeerConnection() {
client_->ClosePeerConnection();
}
void RTCPeerConnectionHandler::OnThermalStateChange(
base::PowerObserver::DeviceThermalState thermal_state) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (is_closed_ || !base::FeatureList::IsEnabled(kWebRtcThermalResource))
return;
if (!thermal_resource_) {
thermal_resource_ = ThermalResource::Create(task_runner_);
native_peer_connection_->AddAdaptationResource(
rtc::scoped_refptr<ThermalResource>(thermal_resource_.get()));
}
thermal_resource_->OnThermalMeasurement(thermal_state);
}
void RTCPeerConnectionHandler::StartEventLog(int output_period_ms) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
// TODO(eladalon): StartRtcEventLog() return value is not useful; remove it
......
......@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/modules/peerconnection/media_stream_track_metrics.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/thermal_resource.h"
#include "third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
#include "third_party/blink/renderer/platform/heap/member.h"
......@@ -213,10 +214,8 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
virtual void CloseClientPeerConnection();
// Invoked when a new thermal state is received from the OS.
// Virtual for testing purposes.
// TODO(https://crbug.com/1094844): When ThermalResource is implemented, have
// it make use of this signal.
virtual void OnThermalStateChange(
base::PowerObserver::DeviceThermalState thermal_state) {}
base::PowerObserver::DeviceThermalState thermal_state);
// Start recording an event log.
void StartEventLog(int output_period_ms);
......@@ -451,6 +450,11 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
bool force_encoded_audio_insertable_streams_ = false;
bool force_encoded_video_insertable_streams_ = false;
// Resources for Adaptation.
// The Thermal Resource is lazily instantiated on platforms where thermal
// signals are supported.
scoped_refptr<ThermalResource> thermal_resource_ = nullptr;
// Record info about the first SessionDescription from the local and
// remote side to record UMA stats once both are set. We only check
// for the first offer or answer. "pranswer"s and "unknown"s (from
......
......@@ -21,6 +21,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -41,6 +42,7 @@
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h"
#include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h"
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
......@@ -1297,4 +1299,40 @@ TEST_F(RTCPeerConnectionHandlerTest, CheckInsertableStreamsConfig) {
}
}
TEST_F(RTCPeerConnectionHandlerTest, ThermalResourceIsDisabledByDefault) {
EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
pc_handler_->OnThermalStateChange(
base::PowerObserver::DeviceThermalState::kCritical);
// A ThermalResource is not created despite the thermal signal.
EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
}
TEST_F(RTCPeerConnectionHandlerTest,
ThermalStateChangeTriggersThermalResourceIfEnabled) {
// Overwrite base::Feature kWebRtcThermalResource's default to ENABLED.
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(kWebRtcThermalResource);
EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
// ThermalResource is created and injected on the fly.
pc_handler_->OnThermalStateChange(
base::PowerObserver::DeviceThermalState::kCritical);
auto resources = mock_peer_connection_->adaptation_resources();
ASSERT_EQ(1u, resources.size());
auto thermal_resource = resources[0];
EXPECT_EQ("ThermalResource", thermal_resource->Name());
// The initial kOveruse is observed.
FakeResourceListener resource_listener;
thermal_resource->SetResourceListener(&resource_listener);
EXPECT_EQ(1u, resource_listener.measurement_count());
EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
resource_listener.latest_measurement());
// ThermalResource responds to new measurements.
pc_handler_->OnThermalStateChange(
base::PowerObserver::DeviceThermalState::kNominal);
EXPECT_EQ(2u, resource_listener.measurement_count());
EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
resource_listener.latest_measurement());
}
} // namespace blink
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h"
#include "base/check.h"
namespace blink {
size_t FakeResourceListener::measurement_count() const {
return measurement_count_;
}
webrtc::ResourceUsageState FakeResourceListener::latest_measurement() const {
DCHECK(measurement_count_);
return latest_measurement_;
}
void FakeResourceListener::OnResourceUsageStateMeasured(
rtc::scoped_refptr<webrtc::Resource> resource,
webrtc::ResourceUsageState usage_state) {
latest_measurement_ = usage_state;
++measurement_count_;
}
} // namespace blink
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_
#include "base/memory/scoped_refptr.h"
#include "third_party/webrtc/api/adaptation/resource.h"
namespace blink {
class FakeResourceListener : public webrtc::ResourceListener {
public:
~FakeResourceListener() override = default;
size_t measurement_count() const;
webrtc::ResourceUsageState latest_measurement() const;
// webrtc::ResourceListener implementation.
void OnResourceUsageStateMeasured(
rtc::scoped_refptr<webrtc::Resource> resource,
webrtc::ResourceUsageState usage_state) override;
private:
size_t measurement_count_ = 0u;
webrtc::ResourceUsageState latest_measurement_ =
webrtc::ResourceUsageState::kUnderuse;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_
......@@ -14,6 +14,9 @@ const int kReportIntervalSeconds = 10;
} // namespace
const base::Feature kWebRtcThermalResource{"kWebRtcThermalResource",
base::FEATURE_DISABLED_BY_DEFAULT};
// static
scoped_refptr<ThermalResource> ThermalResource::Create(
scoped_refptr<base::SequencedTaskRunner> task_runner) {
......
......@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_RESOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_RESOURCE_H_
#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
#include "base/power_monitor/power_observer.h"
#include "base/single_thread_task_runner.h"
......@@ -15,6 +16,8 @@
namespace blink {
MODULES_EXPORT extern const base::Feature kWebRtcThermalResource;
// The ThermalResource reports kOveruse or kUnderuse every 10 seconds(*) while
// it has a registered listener and the DeviceThermalMeasurement is known.
// Because OnThermalMeasurement() only happens when the thermal state changes,
......
......@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/peerconnection/thermal_resource.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
#include "third_party/webrtc/api/adaptation/resource.h"
......@@ -14,29 +15,6 @@ namespace {
const int64_t kReportIntervalMs = 10000;
class FakeResourceListener : public webrtc::ResourceListener {
public:
~FakeResourceListener() override = default;
void OnResourceUsageStateMeasured(
rtc::scoped_refptr<webrtc::Resource> resource,
webrtc::ResourceUsageState usage_state) override {
latest_measurement_ = usage_state;
++measurement_count_;
}
size_t measurement_count() const { return measurement_count_; }
webrtc::ResourceUsageState latest_measurement() const {
DCHECK(measurement_count_);
return latest_measurement_;
}
private:
size_t measurement_count_ = 0u;
webrtc::ResourceUsageState latest_measurement_ =
webrtc::ResourceUsageState::kUnderuse;
};
class ThermalResourceTest : public ::testing::Test {
public:
ThermalResourceTest()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment