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