blob: bedc7b00fbd368f1fc869b816f89adeb4d17458d [file] [log] [blame]
// Copyright 2013 The Chromium Authors
// 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_PEER_CONNECTION_TRACKER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_TRACKER_H_
#include "base/gtest_prod_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "base/types/pass_key.h"
#include "base/values.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/gc_plugin.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
namespace webrtc {
class DataChannelInterface;
} // namespace webrtc
namespace blink {
class LocalFrame;
class MockPeerConnectionTracker;
class PeerConnectionTrackerTest;
class RTCAnswerOptionsPlatform;
class RTCIceCandidatePlatform;
class RTCOfferOptionsPlatform;
class RTCPeerConnectionHandler;
class UserMediaRequest;
class WebLocalFrame;
// This class collects data about each peer connection,
// sends it to the browser process, and handles messages
// from the browser process.
class MODULES_EXPORT PeerConnectionTracker
: public GarbageCollected<PeerConnectionTracker>,
public Supplement<LocalDOMWindow>,
public blink::mojom::blink::PeerConnectionManager {
public:
static const char kSupplementName[];
static PeerConnectionTracker& From(LocalDOMWindow& window);
static PeerConnectionTracker* From(LocalFrame& frame);
static PeerConnectionTracker* From(WebLocalFrame& frame);
PeerConnectionTracker(
LocalDOMWindow& window,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
base::PassKey<PeerConnectionTracker>);
PeerConnectionTracker(const PeerConnectionTracker&) = delete;
PeerConnectionTracker& operator=(const PeerConnectionTracker&) = delete;
~PeerConnectionTracker() override;
// Ctors for tests.
PeerConnectionTracker(
mojo::Remote<mojom::blink::PeerConnectionTrackerHost> host,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
base::PassKey<PeerConnectionTrackerTest> key)
: PeerConnectionTracker(std::move(host), main_thread_task_runner) {}
PeerConnectionTracker(
mojo::Remote<mojom::blink::PeerConnectionTrackerHost> host,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
base::PassKey<MockPeerConnectionTracker> key)
: PeerConnectionTracker(std::move(host), main_thread_task_runner) {}
static void BindToFrame(
LocalFrame* frame,
mojo::PendingReceiver<mojom::blink::PeerConnectionManager> receiver);
enum Source { kSourceLocal, kSourceRemote };
enum Action {
kActionSetLocalDescription,
kActionSetLocalDescriptionImplicit,
kActionSetRemoteDescription,
kActionCreateOffer,
kActionCreateAnswer
};
enum class TransceiverUpdatedReason {
kAddTransceiver,
kAddTrack,
kRemoveTrack,
kSetLocalDescription,
kSetRemoteDescription,
};
// The following methods send an update to the browser process when a
// PeerConnection update happens. The caller should call the Track* methods
// after calling RegisterPeerConnection and before calling
// UnregisterPeerConnection, otherwise the Track* call has no effect.
// Sends an update when a PeerConnection has been created in Javascript. This
// should be called once and only once for each PeerConnection. The
// `pc_handler` is the handler object associated with the PeerConnection,
// the `config` is used to initialize the PeerConnection and the `frame` is
// the WebLocalFrame object representing the page in which the PeerConnection
// is created.
void RegisterPeerConnection(
RTCPeerConnectionHandler* pc_handler,
const webrtc::PeerConnectionInterface::RTCConfiguration& config,
const blink::WebLocalFrame* frame);
// Sends an update when a PeerConnection has been destroyed.
virtual void UnregisterPeerConnection(RTCPeerConnectionHandler* pc_handler);
// Sends an update when createOffer/createAnswer has been called.
// The |pc_handler| is the handler object associated with the PeerConnection,
// the |constraints| is the media constraints used to create the offer/answer.
virtual void TrackCreateOffer(RTCPeerConnectionHandler* pc_handler,
RTCOfferOptionsPlatform* options);
virtual void TrackCreateAnswer(RTCPeerConnectionHandler* pc_handler,
blink::RTCAnswerOptionsPlatform* options);
// Sends an update when setLocalDescription or setRemoteDescription is called.
virtual void TrackSetSessionDescription(RTCPeerConnectionHandler* pc_handler,
const String& sdp,
const String& type,
Source source);
virtual void TrackSetSessionDescriptionImplicit(
RTCPeerConnectionHandler* pc_handler);
// Sends an update when setConfiguration is called.
virtual void TrackSetConfiguration(
RTCPeerConnectionHandler* pc_handler,
const webrtc::PeerConnectionInterface::RTCConfiguration& config);
// Sends an update when an Ice candidate is added.
virtual void TrackAddIceCandidate(RTCPeerConnectionHandler* pc_handler,
RTCIceCandidatePlatform* candidate,
Source source,
bool succeeded);
// Sends an update when an Ice candidate error is receiver.
virtual void TrackIceCandidateError(RTCPeerConnectionHandler* pc_handler,
const String& address,
absl::optional<uint16_t> port,
const String& host_candidate,
const String& url,
int error_code,
const String& error_text);
// Sends an update when a transceiver is added, modified or removed. This can
// happen as a result of any of the methods indicated by |reason|.
// Example events: "transceiverAdded", "transceiverModified".
// See peer_connection_tracker_unittest.cc for expected resulting event
// strings.
virtual void TrackAddTransceiver(RTCPeerConnectionHandler* pc_handler,
TransceiverUpdatedReason reason,
const RTCRtpTransceiverPlatform& transceiver,
size_t transceiver_index);
virtual void TrackModifyTransceiver(
RTCPeerConnectionHandler* pc_handler,
TransceiverUpdatedReason reason,
const RTCRtpTransceiverPlatform& transceiver,
size_t transceiver_index);
// Sends an update when a DataChannel is created.
virtual void TrackCreateDataChannel(
RTCPeerConnectionHandler* pc_handler,
const webrtc::DataChannelInterface* data_channel,
Source source);
// Sends an update when a PeerConnection has been closed.
virtual void TrackClose(RTCPeerConnectionHandler* pc_handler);
// Sends an update when the signaling state of a PeerConnection has changed.
virtual void TrackSignalingStateChange(
RTCPeerConnectionHandler* pc_handler,
webrtc::PeerConnectionInterface::SignalingState state);
// Sends an update when the ICE connection state of a PeerConnection has
// changed.
virtual void TrackIceConnectionStateChange(
RTCPeerConnectionHandler* pc_handler,
webrtc::PeerConnectionInterface::IceConnectionState state);
// Sends an update when the connection state
// of a PeerConnection has changed.
virtual void TrackConnectionStateChange(
RTCPeerConnectionHandler* pc_handler,
webrtc::PeerConnectionInterface::PeerConnectionState state);
// Sends an update when the Ice gathering state
// of a PeerConnection has changed.
virtual void TrackIceGatheringStateChange(
RTCPeerConnectionHandler* pc_handler,
webrtc::PeerConnectionInterface::IceGatheringState state);
// Sends an update when the SetSessionDescription or CreateOffer or
// CreateAnswer callbacks are called.
virtual void TrackSessionDescriptionCallback(
RTCPeerConnectionHandler* pc_handler,
Action action,
const String& type,
const String& value);
// Sends an update when the session description's ID is set.
virtual void TrackSessionId(RTCPeerConnectionHandler* pc_handler,
const String& session_id);
// Sends an update when onRenegotiationNeeded is called.
virtual void TrackOnRenegotiationNeeded(RTCPeerConnectionHandler* pc_handler);
// Sends an update when getUserMedia is called.
virtual void TrackGetUserMedia(UserMediaRequest* user_media_request);
// Sends an update when getUserMedia resolveѕ with a stream.
virtual void TrackGetUserMediaSuccess(UserMediaRequest* user_media_request,
const MediaStream* stream);
// Sends an update when getUserMedia fails with an error.
virtual void TrackGetUserMediaFailure(UserMediaRequest* user_media_request,
const String& error,
const String& error_message);
// Sends an update when getDisplayMedia is called.
virtual void TrackGetDisplayMedia(UserMediaRequest* user_media_request);
// Sends an update when getDisplayMedia resolveѕ with a stream.
virtual void TrackGetDisplayMediaSuccess(UserMediaRequest* user_media_request,
MediaStream* stream);
// Sends an update when getDisplayMedia fails with an error.
virtual void TrackGetDisplayMediaFailure(UserMediaRequest* user_media_request,
const String& error,
const String& error_message);
// Sends a new fragment on an RtcEventLog.
virtual void TrackRtcEventLogWrite(RTCPeerConnectionHandler* pc_handler,
const WTF::Vector<uint8_t>& output);
void Trace(Visitor* visitor) const override {
visitor->Trace(receiver_);
Supplement<LocalDOMWindow>::Trace(visitor);
}
private:
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend);
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnThermalStateChange);
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSpeedLimitChange);
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest,
ReportInitialThermalState);
PeerConnectionTracker(
mojo::Remote<mojom::blink::PeerConnectionTrackerHost> host,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
void Bind(mojo::PendingReceiver<blink::mojom::blink::PeerConnectionManager>
receiver);
// Assign a local ID to a peer connection so that the browser process can
// uniquely identify a peer connection in the renderer process.
// The return value will always be positive.
int GetNextLocalID();
// Looks up a handler in our map and if found, returns its ID. If the handler
// is not registered, the return value will be -1.
int GetLocalIDForHandler(RTCPeerConnectionHandler* handler) const;
void TrackTransceiver(const char* callback_type_ending,
RTCPeerConnectionHandler* pc_handler,
PeerConnectionTracker::TransceiverUpdatedReason reason,
const RTCRtpTransceiverPlatform& transceiver,
size_t transceiver_index);
// PeerConnectionTracker implementation.
void OnSuspend() override;
void OnThermalStateChange(
mojom::blink::DeviceThermalState thermal_state) override;
void OnSpeedLimitChange(int32_t speed_limit) override;
void StartEventLog(int peer_connection_local_id,
int output_period_ms) override;
void StopEventLog(int peer_connection_local_id) override;
void GetStandardStats() override;
void GetLegacyStats() override;
// Called to deliver an update to the host (PeerConnectionTrackerHost).
// |local_id| - The id of the registered RTCPeerConnectionHandler.
// Using an id instead of the hander pointer is done on purpose
// to force doing the lookup before building the callback data
// in case the handler isn't registered.
// |callback_type| - A string, most often static, that represents the type
// of operation that the data stored in |value| comes from.
// E.g. "createOffer", "createAnswer",
// "setRemoteDescription" etc.
// |value| - A json serialized string containing all the information for the
// update event.
void SendPeerConnectionUpdate(int local_id,
const String& callback_type,
const String& value);
void AddStandardStats(int lid, base::Value::List value);
void AddLegacyStats(int lid, base::Value::List value);
// This map stores the local ID assigned to each RTCPeerConnectionHandler.
typedef WTF::HashMap<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap;
PeerConnectionLocalIdMap peer_connection_local_id_map_;
mojom::blink::DeviceThermalState current_thermal_state_ =
mojom::blink::DeviceThermalState::kUnknown;
int32_t current_speed_limit_ = mojom::blink::kSpeedLimitMax;
THREAD_CHECKER(main_thread_);
GC_PLUGIN_IGNORE("https://crbug.com/1381979")
mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost>
peer_connection_tracker_host_;
HeapMojoReceiver<blink::mojom::blink::PeerConnectionManager,
PeerConnectionTracker>
receiver_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_TRACKER_H_