1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <memory> 20 21 #include <api/peer_connection_interface.h> 22 #include <json/json.h> 23 24 #include "common/libs/utils/result.h" 25 #include "host/frontend/webrtc/libcommon/peer_signaling_handler.h" 26 27 namespace cuttlefish { 28 namespace webrtc_streaming { 29 30 // Creating the peer connection is different on the client and device, but for 31 // both the pc needs to be created during the signaling process. 32 class PeerConnectionBuilder { 33 public: 34 virtual ~PeerConnectionBuilder() = default; 35 virtual Result<rtc::scoped_refptr<webrtc::PeerConnectionInterface>> Build( 36 webrtc::PeerConnectionObserver& observer, 37 const std::vector<webrtc::PeerConnectionInterface::IceServer>& 38 per_connection_servers) = 0; 39 }; 40 41 // Encapsulates the signaling protocol, which is mostly the same for client and 42 // device. Devices will create a connection controller for each new client and 43 // simply provide implementations of the callbacks in 44 // ConnectionController::Observer. Clients must additionally call RequestOffer 45 // to start the signaling process. 46 class ConnectionController : public webrtc::PeerConnectionObserver { 47 public: 48 // These callbacks will be called from the signaling thread. Implementations 49 // should return as soon as possible, particularly not blocking on IO. 50 // Implementations must never destroy the ConnectionController object from 51 // inside these callbacks as that would lead to undefined behavior. 52 // TODO (b/240578845): This avoids having to create an extra thread per 53 // client just to monitor changes in the device side, but opens problems by 54 // allowing it to react to state changes on a peer connection callback. The 55 // device already has code to avoid these issues, but the ideal solution 56 // would be for this callback to be posted to a thread or not to be used at 57 // all. 58 class Observer { 59 public: 60 virtual ~Observer() = default; 61 virtual void OnConnectionStateChange( 62 Result<webrtc::PeerConnectionInterface::PeerConnectionState> 63 status) = 0; 64 65 // Called when new media tracks are added to the peer connection. 66 virtual void OnTrack( 67 rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver) = 0; 68 // Called when media tracks are removed from the peer connection. 69 virtual void OnRemoveTrack( 70 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) = 0; 71 // Called when a data channel is added to the peer connection. 72 virtual void OnDataChannel( 73 rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) = 0; 74 }; 75 76 ConnectionController(PeerSignalingHandler& sig_handler, 77 PeerConnectionBuilder& connection_builder, 78 Observer& observer); 79 ~ConnectionController() override = default; 80 81 // Sends a request-offer message to the peer to kickstart the signaling 82 // process. 83 Result<void> RequestOffer( 84 const std::vector<webrtc::PeerConnectionInterface::IceServer>& 85 ice_servers); 86 87 // This class doesn't poll for signaling messages from the server, instead 88 // users must do that themselves and provide them here for the connection 89 // controller to process them. As the result of this processing some callbacks 90 // may be called or new messages may be sent to the peer, most likely after 91 // the function returns, but that's not guaranteed. 92 void HandleSignalingMessage(const Json::Value& msg); 93 peer_connection()94 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection() { 95 return peer_connection_; 96 } 97 98 // webrtc::PeerConnectionObserver implementation 99 void OnSignalingChange( 100 webrtc::PeerConnectionInterface::SignalingState new_state) override; 101 void OnAddStream( 102 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override; 103 void OnRemoveStream( 104 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override; 105 void OnDataChannel( 106 rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override; 107 void OnRenegotiationNeeded() override; 108 void OnStandardizedIceConnectionChange( 109 webrtc::PeerConnectionInterface::IceConnectionState new_state) override; 110 void OnConnectionChange( 111 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override; 112 void OnIceGatheringChange( 113 webrtc::PeerConnectionInterface::IceGatheringState new_state) override; 114 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override; 115 void OnIceCandidateError(const std::string& address, int port, 116 const std::string& url, int error_code, 117 const std::string& error_text) override; 118 void OnIceCandidatesRemoved( 119 const std::vector<cricket::Candidate>& candidates) override; 120 // The following can be overridden but are not needed by either the device or 121 // client at the moement. void OnIceConnectionReceivingChange(bool receiving) 122 // override; void OnIceSelectedCandidatePairChanged( const 123 // cricket::CandidatePairChangeEvent& event) override; void OnAddTrack( 124 // rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, 125 // const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& 126 // streams) override; 127 // void OnInterestingUsage(int usage_pattern) override; 128 void OnTrack( 129 rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver) override; 130 void OnRemoveTrack( 131 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override; 132 133 private: 134 friend class CreateSessionDescriptionObserverIntermediate; 135 friend class SetSessionDescriptionObserverIntermediate; 136 friend class SetRemoteDescriptionObserverIntermediate; 137 void CreateOffer(); 138 void AddPendingIceCandidates(); 139 void FailConnection(const std::string& message); 140 141 Result<void> HandleSignalingMessageInner(const Json::Value& msg); 142 Result<void> OnOfferRequestMsg( 143 const std::vector<webrtc::PeerConnectionInterface::IceServer>& 144 ice_servers); 145 Result<void> OnOfferMsg( 146 std::unique_ptr<webrtc::SessionDescriptionInterface> offer); 147 Result<void> OnAnswerMsg( 148 std::unique_ptr<webrtc::SessionDescriptionInterface> offer); 149 Result<void> OnIceCandidateMsg( 150 std::unique_ptr<webrtc::IceCandidateInterface> ice_candidate); 151 Result<void> OnErrorMsg(const std::string& msg); 152 153 webrtc::CreateSessionDescriptionObserver* ThisAsCreateSDPObserver(); 154 webrtc::SetSessionDescriptionObserver* ThisAsSetSDPObserver(); 155 rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> 156 ThisAsSetRemoteSDPObserver(); 157 158 Result<void> OnCreateSDPSuccess(webrtc::SessionDescriptionInterface* desc); 159 void OnCreateSDPFailure(const webrtc::RTCError& error); 160 void OnSetLocalDescriptionSuccess(); 161 void OnSetLocalDescriptionFailure(const webrtc::RTCError& error); 162 void OnSetRemoteDescriptionComplete(const webrtc::RTCError& error); 163 164 PeerSignalingHandler& sig_handler_; 165 PeerConnectionBuilder& connection_builder_; 166 Observer& observer_; 167 168 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; 169 std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> 170 pending_ice_candidates_; 171 172 // To await for a connection to be established: 173 std::mutex status_mtx_; 174 std::condition_variable status_cond_var_; 175 Result<webrtc::PeerConnectionInterface::PeerConnectionState> 176 connection_status_; 177 }; 178 179 } // namespace webrtc_streaming 180 } // namespace cuttlefish 181