• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 #define LOG_TAG "ClientHandler"
18 
19 #include "host/frontend/webrtc/lib/client_handler.h"
20 
21 #include <vector>
22 
23 #include <json/json.h>
24 #include <json/writer.h>
25 #include <netdb.h>
26 #include <openssl/rand.h>
27 
28 #include <android-base/logging.h>
29 
30 #include "host/frontend/webrtc/lib/keyboard.h"
31 #include "host/frontend/webrtc/lib/utils.h"
32 #include "host/libs/config/cuttlefish_config.h"
33 
34 namespace cuttlefish {
35 namespace webrtc_streaming {
36 
37 namespace {
38 
39 static constexpr auto kInputChannelLabel = "input-channel";
40 static constexpr auto kAdbChannelLabel = "adb-channel";
41 static constexpr auto kBluetoothChannelLabel = "bluetooth-channel";
42 
43 class CvdCreateSessionDescriptionObserver
44     : public webrtc::CreateSessionDescriptionObserver {
45  public:
CvdCreateSessionDescriptionObserver(std::weak_ptr<ClientHandler> client_handler)46   CvdCreateSessionDescriptionObserver(
47       std::weak_ptr<ClientHandler> client_handler)
48       : client_handler_(client_handler) {}
49 
OnSuccess(webrtc::SessionDescriptionInterface * desc)50   void OnSuccess(webrtc::SessionDescriptionInterface *desc) override {
51     auto client_handler = client_handler_.lock();
52     if (client_handler) {
53       client_handler->OnCreateSDPSuccess(desc);
54     }
55   }
OnFailure(webrtc::RTCError error)56   void OnFailure(webrtc::RTCError error) override {
57     auto client_handler = client_handler_.lock();
58     if (client_handler) {
59       client_handler->OnCreateSDPFailure(error);
60     }
61   }
62 
63  private:
64   std::weak_ptr<ClientHandler> client_handler_;
65 };
66 
67 class CvdSetSessionDescriptionObserver
68     : public webrtc::SetSessionDescriptionObserver {
69  public:
CvdSetSessionDescriptionObserver(std::weak_ptr<ClientHandler> client_handler)70   CvdSetSessionDescriptionObserver(std::weak_ptr<ClientHandler> client_handler)
71       : client_handler_(client_handler) {}
72 
OnSuccess()73   void OnSuccess() override {
74     // local description set, nothing else to do
75   }
OnFailure(webrtc::RTCError error)76   void OnFailure(webrtc::RTCError error) override {
77     auto client_handler = client_handler_.lock();
78     if (client_handler) {
79       client_handler->OnSetSDPFailure(error);
80     }
81   }
82 
83  private:
84   std::weak_ptr<ClientHandler> client_handler_;
85 };
86 
87 class CvdOnSetRemoteDescription
88     : public webrtc::SetRemoteDescriptionObserverInterface {
89  public:
CvdOnSetRemoteDescription(std::function<void (webrtc::RTCError error)> on_error)90   CvdOnSetRemoteDescription(
91       std::function<void(webrtc::RTCError error)> on_error)
92       : on_error_(on_error) {}
93 
OnSetRemoteDescriptionComplete(webrtc::RTCError error)94   void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
95     on_error_(error);
96   }
97 
98  private:
99   std::function<void(webrtc::RTCError error)> on_error_;
100 };
101 
102 }  // namespace
103 
104 class InputChannelHandler : public webrtc::DataChannelObserver {
105  public:
106   InputChannelHandler(
107       rtc::scoped_refptr<webrtc::DataChannelInterface> input_channel,
108       std::shared_ptr<ConnectionObserver> observer);
109   ~InputChannelHandler() override;
110 
111   void OnStateChange() override;
112   void OnMessage(const webrtc::DataBuffer &msg) override;
113 
114  private:
115   rtc::scoped_refptr<webrtc::DataChannelInterface> input_channel_;
116   std::shared_ptr<ConnectionObserver> observer_;
117 };
118 
119 class AdbChannelHandler : public webrtc::DataChannelObserver {
120  public:
121   AdbChannelHandler(
122       rtc::scoped_refptr<webrtc::DataChannelInterface> adb_channel,
123       std::shared_ptr<ConnectionObserver> observer);
124   ~AdbChannelHandler() override;
125 
126   void OnStateChange() override;
127   void OnMessage(const webrtc::DataBuffer &msg) override;
128 
129  private:
130   rtc::scoped_refptr<webrtc::DataChannelInterface> adb_channel_;
131   std::shared_ptr<ConnectionObserver> observer_;
132   bool channel_open_reported_ = false;
133 };
134 
135 class ControlChannelHandler : public webrtc::DataChannelObserver {
136  public:
137   ControlChannelHandler(
138       rtc::scoped_refptr<webrtc::DataChannelInterface> control_channel,
139       std::shared_ptr<ConnectionObserver> observer);
140   ~ControlChannelHandler() override;
141 
142   void OnStateChange() override;
143   void OnMessage(const webrtc::DataBuffer &msg) override;
144 
145   void Send(const Json::Value &message);
146   void Send(const uint8_t *msg, size_t size, bool binary);
147 
148  private:
149   rtc::scoped_refptr<webrtc::DataChannelInterface> control_channel_;
150   std::shared_ptr<ConnectionObserver> observer_;
151 };
152 
153 class BluetoothChannelHandler : public webrtc::DataChannelObserver {
154  public:
155   BluetoothChannelHandler(
156       rtc::scoped_refptr<webrtc::DataChannelInterface> bluetooth_channel,
157       std::shared_ptr<ConnectionObserver> observer);
158   ~BluetoothChannelHandler() override;
159 
160   void OnStateChange() override;
161   void OnMessage(const webrtc::DataBuffer &msg) override;
162 
163  private:
164   rtc::scoped_refptr<webrtc::DataChannelInterface> bluetooth_channel_;
165   std::shared_ptr<ConnectionObserver> observer_;
166   bool channel_open_reported_ = false;
167 };
168 
InputChannelHandler(rtc::scoped_refptr<webrtc::DataChannelInterface> input_channel,std::shared_ptr<ConnectionObserver> observer)169 InputChannelHandler::InputChannelHandler(
170     rtc::scoped_refptr<webrtc::DataChannelInterface> input_channel,
171     std::shared_ptr<ConnectionObserver> observer)
172     : input_channel_(input_channel), observer_(observer) {
173   input_channel->RegisterObserver(this);
174 }
175 
~InputChannelHandler()176 InputChannelHandler::~InputChannelHandler() {
177   input_channel_->UnregisterObserver();
178 }
179 
OnStateChange()180 void InputChannelHandler::OnStateChange() {
181   LOG(VERBOSE) << "Input channel state changed to "
182                << webrtc::DataChannelInterface::DataStateString(
183                       input_channel_->state());
184 }
185 
OnMessage(const webrtc::DataBuffer & msg)186 void InputChannelHandler::OnMessage(const webrtc::DataBuffer &msg) {
187   if (msg.binary) {
188     // TODO (jemoreira) consider binary protocol to avoid JSON parsing overhead
189     LOG(ERROR) << "Received invalid (binary) data on input channel";
190     return;
191   }
192   auto size = msg.size();
193 
194   Json::Value evt;
195   Json::CharReaderBuilder builder;
196   std::unique_ptr<Json::CharReader> json_reader(builder.newCharReader());
197   std::string errorMessage;
198   auto str = msg.data.cdata<char>();
199   if (!json_reader->parse(str, str + size, &evt, &errorMessage) < 0) {
200     LOG(ERROR) << "Received invalid JSON object over input channel: "
201                << errorMessage;
202     return;
203   }
204   if (!evt.isMember("type") || !evt["type"].isString()) {
205     LOG(ERROR) << "Input event doesn't have a valid 'type' field: "
206                << evt.toStyledString();
207     return;
208   }
209   auto event_type = evt["type"].asString();
210   if (event_type == "mouse") {
211     auto result =
212         ValidationResult::ValidateJsonObject(evt, "mouse",
213                            {{"down", Json::ValueType::intValue},
214                             {"x", Json::ValueType::intValue},
215                             {"y", Json::ValueType::intValue},
216                             {"display_label", Json::ValueType::stringValue}});
217     if (!result.ok()) {
218       LOG(ERROR) << result.error();
219       return;
220     }
221     auto label = evt["display_label"].asString();
222     int32_t down = evt["down"].asInt();
223     int32_t x = evt["x"].asInt();
224     int32_t y = evt["y"].asInt();
225 
226     observer_->OnTouchEvent(label, x, y, down);
227   } else if (event_type == "multi-touch") {
228     auto result =
229         ValidationResult::ValidateJsonObject(evt, "multi-touch",
230                            {{"id", Json::ValueType::arrayValue},
231                             {"down", Json::ValueType::intValue},
232                             {"x", Json::ValueType::arrayValue},
233                             {"y", Json::ValueType::arrayValue},
234                             {"slot", Json::ValueType::arrayValue},
235                             {"display_label", Json::ValueType::stringValue}});
236     if (!result.ok()) {
237       LOG(ERROR) << result.error();
238       return;
239     }
240 
241     auto label = evt["display_label"].asString();
242     auto idArr = evt["id"];
243     int32_t down = evt["down"].asInt();
244     auto xArr = evt["x"];
245     auto yArr = evt["y"];
246     auto slotArr = evt["slot"];
247     int size = evt["id"].size();
248 
249     observer_->OnMultiTouchEvent(label, idArr, slotArr, xArr, yArr, down, size);
250   } else if (event_type == "keyboard") {
251     auto result =
252         ValidationResult::ValidateJsonObject(evt, "keyboard",
253                            {{"event_type", Json::ValueType::stringValue},
254                             {"keycode", Json::ValueType::stringValue}});
255     if (!result.ok()) {
256       LOG(ERROR) << result.error();
257       return;
258     }
259     auto down = evt["event_type"].asString() == std::string("keydown");
260     auto code = DomKeyCodeToLinux(evt["keycode"].asString());
261     observer_->OnKeyboardEvent(code, down);
262   } else {
263     LOG(ERROR) << "Unrecognized event type: " << event_type;
264     return;
265   }
266 }
267 
AdbChannelHandler(rtc::scoped_refptr<webrtc::DataChannelInterface> adb_channel,std::shared_ptr<ConnectionObserver> observer)268 AdbChannelHandler::AdbChannelHandler(
269     rtc::scoped_refptr<webrtc::DataChannelInterface> adb_channel,
270     std::shared_ptr<ConnectionObserver> observer)
271     : adb_channel_(adb_channel), observer_(observer) {
272   adb_channel->RegisterObserver(this);
273 }
274 
~AdbChannelHandler()275 AdbChannelHandler::~AdbChannelHandler() { adb_channel_->UnregisterObserver(); }
276 
OnStateChange()277 void AdbChannelHandler::OnStateChange() {
278   LOG(VERBOSE) << "Adb channel state changed to "
279                << webrtc::DataChannelInterface::DataStateString(
280                       adb_channel_->state());
281 }
282 
OnMessage(const webrtc::DataBuffer & msg)283 void AdbChannelHandler::OnMessage(const webrtc::DataBuffer &msg) {
284   // Report the adb channel as open on the first message received instead of at
285   // channel open, this avoids unnecessarily connecting to the adb daemon for
286   // clients that don't use ADB.
287   if (!channel_open_reported_) {
288     observer_->OnAdbChannelOpen([this](const uint8_t *msg, size_t size) {
289       webrtc::DataBuffer buffer(rtc::CopyOnWriteBuffer(msg, size),
290                                 true /*binary*/);
291       // TODO (b/185832105): When the SCTP channel is congested data channel
292       // messages are buffered up to 16MB, when the buffer is full the channel
293       // is abruptly closed. Keep track of the buffered data to avoid losing the
294       // adb data channel.
295       adb_channel_->Send(buffer);
296       return true;
297     });
298     channel_open_reported_ = true;
299   }
300   observer_->OnAdbMessage(msg.data.cdata(), msg.size());
301 }
302 
ControlChannelHandler(rtc::scoped_refptr<webrtc::DataChannelInterface> control_channel,std::shared_ptr<ConnectionObserver> observer)303 ControlChannelHandler::ControlChannelHandler(
304     rtc::scoped_refptr<webrtc::DataChannelInterface> control_channel,
305     std::shared_ptr<ConnectionObserver> observer)
306     : control_channel_(control_channel), observer_(observer) {
307   control_channel->RegisterObserver(this);
308   observer_->OnControlChannelOpen([this](const Json::Value& message) {
309     this->Send(message);
310     return true;
311   });
312 }
313 
~ControlChannelHandler()314 ControlChannelHandler::~ControlChannelHandler() {
315   control_channel_->UnregisterObserver();
316 }
317 
OnStateChange()318 void ControlChannelHandler::OnStateChange() {
319   LOG(VERBOSE) << "Control channel state changed to "
320                << webrtc::DataChannelInterface::DataStateString(
321                       control_channel_->state());
322 }
323 
OnMessage(const webrtc::DataBuffer & msg)324 void ControlChannelHandler::OnMessage(const webrtc::DataBuffer &msg) {
325   observer_->OnControlMessage(msg.data.cdata(), msg.size());
326 }
327 
Send(const Json::Value & message)328 void ControlChannelHandler::Send(const Json::Value& message) {
329   Json::StreamWriterBuilder factory;
330   std::string message_string = Json::writeString(factory, message);
331   Send(reinterpret_cast<const uint8_t*>(message_string.c_str()),
332        message_string.size(), /*binary=*/false);
333 }
334 
Send(const uint8_t * msg,size_t size,bool binary)335 void ControlChannelHandler::Send(const uint8_t *msg, size_t size, bool binary) {
336   webrtc::DataBuffer buffer(rtc::CopyOnWriteBuffer(msg, size), binary);
337   control_channel_->Send(buffer);
338 }
339 
BluetoothChannelHandler(rtc::scoped_refptr<webrtc::DataChannelInterface> bluetooth_channel,std::shared_ptr<ConnectionObserver> observer)340 BluetoothChannelHandler::BluetoothChannelHandler(
341     rtc::scoped_refptr<webrtc::DataChannelInterface> bluetooth_channel,
342     std::shared_ptr<ConnectionObserver> observer)
343     : bluetooth_channel_(bluetooth_channel), observer_(observer) {
344   bluetooth_channel_->RegisterObserver(this);
345 }
346 
~BluetoothChannelHandler()347 BluetoothChannelHandler::~BluetoothChannelHandler() {
348   bluetooth_channel_->UnregisterObserver();
349 }
350 
OnStateChange()351 void BluetoothChannelHandler::OnStateChange() {
352   LOG(VERBOSE) << "Bluetooth channel state changed to "
353                << webrtc::DataChannelInterface::DataStateString(
354                       bluetooth_channel_->state());
355 }
356 
OnMessage(const webrtc::DataBuffer & msg)357 void BluetoothChannelHandler::OnMessage(const webrtc::DataBuffer &msg) {
358   // Notify bluetooth channel opening when actually using the channel,
359   // it has the same reason with AdbChannelHandler::OnMessage,
360   // to avoid unnecessarily connection for Rootcanal.
361   if (channel_open_reported_ == false) {
362     channel_open_reported_ = true;
363     observer_->OnBluetoothChannelOpen([this](const uint8_t *msg, size_t size) {
364       webrtc::DataBuffer buffer(rtc::CopyOnWriteBuffer(msg, size),
365                                 true /*binary*/);
366       // TODO (b/185832105): When the SCTP channel is congested data channel
367       // messages are buffered up to 16MB, when the buffer is full the channel
368       // is abruptly closed. Keep track of the buffered data to avoid losing the
369       // adb data channel.
370       bluetooth_channel_->Send(buffer);
371       return true;
372     });
373   }
374 
375   observer_->OnBluetoothMessage(msg.data.cdata(), msg.size());
376 }
377 
Create(int client_id,std::shared_ptr<ConnectionObserver> observer,std::function<void (const Json::Value &)> send_to_client_cb,std::function<void ()> on_connection_closed_cb)378 std::shared_ptr<ClientHandler> ClientHandler::Create(
379     int client_id, std::shared_ptr<ConnectionObserver> observer,
380     std::function<void(const Json::Value &)> send_to_client_cb,
381     std::function<void()> on_connection_closed_cb) {
382   return std::shared_ptr<ClientHandler>(new ClientHandler(
383       client_id, observer, send_to_client_cb, on_connection_closed_cb));
384 }
385 
ClientHandler(int client_id,std::shared_ptr<ConnectionObserver> observer,std::function<void (const Json::Value &)> send_to_client_cb,std::function<void ()> on_connection_closed_cb)386 ClientHandler::ClientHandler(
387     int client_id, std::shared_ptr<ConnectionObserver> observer,
388     std::function<void(const Json::Value &)> send_to_client_cb,
389     std::function<void()> on_connection_closed_cb)
390     : client_id_(client_id),
391       observer_(observer),
392       send_to_client_(send_to_client_cb),
393       on_connection_closed_cb_(on_connection_closed_cb) {}
394 
~ClientHandler()395 ClientHandler::~ClientHandler() {
396   for (auto &data_channel : data_channels_) {
397     data_channel->UnregisterObserver();
398   }
399 }
400 
SetPeerConnection(rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection)401 bool ClientHandler::SetPeerConnection(
402     rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection) {
403   peer_connection_ = peer_connection;
404 
405   // libwebrtc configures the video encoder with a start bitrate of just 300kbs
406   // which causes it to drop the first 4 frames it receives. Any value over 2Mbs
407   // will be capped at 2Mbs when passed to the encoder by the peer_connection
408   // object, so we pass the maximum possible value here.
409   webrtc::BitrateSettings bitrate_settings;
410   bitrate_settings.start_bitrate_bps = 2000000; // 2Mbs
411   peer_connection_->SetBitrate(bitrate_settings);
412   // At least one data channel needs to be created on the side that makes the
413   // SDP offer (the device) for data channels to be enabled at all.
414   // This channel is meant to carry control commands from the client.
415   auto control_channel = peer_connection_->CreateDataChannel(
416       "device-control", nullptr /* config */);
417   if (!control_channel) {
418     LOG(ERROR) << "Failed to create control data channel";
419     return false;
420   }
421   control_handler_.reset(new ControlChannelHandler(control_channel, observer_));
422   return true;
423 }
424 
AddDisplay(rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track,const std::string & label)425 bool ClientHandler::AddDisplay(
426     rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track,
427     const std::string &label) {
428   // Send each track as part of a different stream with the label as id
429   auto err_or_sender =
430       peer_connection_->AddTrack(video_track, {label} /* stream_id */);
431   if (!err_or_sender.ok()) {
432     LOG(ERROR) << "Failed to add video track to the peer connection";
433     return false;
434   }
435   // TODO (b/154138394): use the returned sender (err_or_sender.value()) to
436   // remove the display from the connection.
437   return true;
438 }
439 
AddAudio(rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track,const std::string & label)440 bool ClientHandler::AddAudio(
441     rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track,
442     const std::string &label) {
443   // Send each track as part of a different stream with the label as id
444   auto err_or_sender =
445       peer_connection_->AddTrack(audio_track, {label} /* stream_id */);
446   if (!err_or_sender.ok()) {
447     LOG(ERROR) << "Failed to add video track to the peer connection";
448     return false;
449   }
450   return true;
451 }
452 
LogAndReplyError(const std::string & error_msg) const453 void ClientHandler::LogAndReplyError(const std::string &error_msg) const {
454   LOG(ERROR) << error_msg;
455   Json::Value reply;
456   reply["type"] = "error";
457   reply["error"] = error_msg;
458   send_to_client_(reply);
459 }
460 
OnCreateSDPSuccess(webrtc::SessionDescriptionInterface * desc)461 void ClientHandler::OnCreateSDPSuccess(
462     webrtc::SessionDescriptionInterface *desc) {
463   std::string offer_str;
464   desc->ToString(&offer_str);
465   peer_connection_->SetLocalDescription(
466       // The peer connection wraps this raw pointer with a scoped_refptr, so
467       // it's guaranteed to be deleted at some point
468       new rtc::RefCountedObject<CvdSetSessionDescriptionObserver>(
469           weak_from_this()),
470       desc);
471   // The peer connection takes ownership of the description so it should not be
472   // used after this
473   desc = nullptr;
474 
475   Json::Value reply;
476   reply["type"] = "offer";
477   reply["sdp"] = offer_str;
478 
479   state_ = State::kAwaitingAnswer;
480   send_to_client_(reply);
481 }
482 
OnCreateSDPFailure(webrtc::RTCError error)483 void ClientHandler::OnCreateSDPFailure(webrtc::RTCError error) {
484   state_ = State::kFailed;
485   LogAndReplyError(error.message());
486   Close();
487 }
488 
OnSetSDPFailure(webrtc::RTCError error)489 void ClientHandler::OnSetSDPFailure(webrtc::RTCError error) {
490   state_ = State::kFailed;
491   LogAndReplyError(error.message());
492   LOG(ERROR) << "Error setting local description: Either there is a bug in "
493                 "libwebrtc or the local description was (incorrectly) modified "
494                 "after creating it";
495   Close();
496 }
497 
HandleMessage(const Json::Value & message)498 void ClientHandler::HandleMessage(const Json::Value &message) {
499   {
500     auto result = ValidationResult::ValidateJsonObject(message, "",
501                                      {{"type", Json::ValueType::stringValue}});
502     if (!result.ok()) {
503       LogAndReplyError(result.error());
504       return;
505     }
506   }
507   auto type = message["type"].asString();
508   if (type == "request-offer") {
509     // Can't check for state being different that kNew because renegotiation can
510     // start in any state after the answer is returned.
511     if (state_ == State::kCreatingOffer) {
512       // An offer has been requested already
513       LogAndReplyError("Multiple requests for offer received from single client");
514       return;
515     }
516     state_ = State::kCreatingOffer;
517     peer_connection_->CreateOffer(
518         // No memory leak here because this is a ref counted objects and the
519         // peer connection immediately wraps it with a scoped_refptr
520         new rtc::RefCountedObject<CvdCreateSessionDescriptionObserver>(
521             weak_from_this()),
522         webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
523     // The created offer wil be sent to the client on
524     // OnSuccess(webrtc::SessionDescriptionInterface* desc)
525   } else if (type == "answer") {
526     if (state_ != State::kAwaitingAnswer) {
527       LogAndReplyError("Received unexpected SDP answer");
528       return;
529     }
530     auto result = ValidationResult::ValidateJsonObject(message, type,
531                                      {{"sdp", Json::ValueType::stringValue}});
532     if (!result.ok()) {
533       LogAndReplyError(result.error());
534       return;
535     }
536     auto remote_desc_str = message["sdp"].asString();
537     auto remote_desc = webrtc::CreateSessionDescription(
538         webrtc::SdpType::kAnswer, remote_desc_str, nullptr /*error*/);
539     if (!remote_desc) {
540       LogAndReplyError("Failed to parse answer.");
541       return;
542     }
543     rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> observer(
544         new rtc::RefCountedObject<CvdOnSetRemoteDescription>(
545             [this](webrtc::RTCError error) {
546               if (!error.ok()) {
547                 LogAndReplyError(error.message());
548                 // The remote description was rejected, this client can't be
549                 // trusted anymore.
550                 Close();
551               }
552             }));
553     peer_connection_->SetRemoteDescription(std::move(remote_desc), observer);
554     state_ = State::kConnecting;
555 
556   } else if (type == "ice-candidate") {
557     {
558       auto result = ValidationResult::ValidateJsonObject(
559           message, type, {{"candidate", Json::ValueType::objectValue}});
560       if (!result.ok()) {
561         LogAndReplyError(result.error());
562         return;
563       }
564     }
565     auto candidate_json = message["candidate"];
566     {
567       auto result =
568           ValidationResult::ValidateJsonObject(candidate_json,
569                                                "ice-candidate/candidate",
570                              {
571                                  {"sdpMid", Json::ValueType::stringValue},
572                                  {"candidate", Json::ValueType::stringValue},
573                                  {"sdpMLineIndex", Json::ValueType::intValue},
574                              });
575       if (!result.ok()) {
576         LogAndReplyError(result.error());
577         return;
578       }
579     }
580     auto mid = candidate_json["sdpMid"].asString();
581     auto candidate_sdp = candidate_json["candidate"].asString();
582     auto line_index = candidate_json["sdpMLineIndex"].asInt();
583 
584     std::unique_ptr<webrtc::IceCandidateInterface> candidate(
585         webrtc::CreateIceCandidate(mid, line_index, candidate_sdp,
586                                    nullptr /*error*/));
587     if (!candidate) {
588       LogAndReplyError("Failed to parse ICE candidate");
589       return;
590     }
591     peer_connection_->AddIceCandidate(std::move(candidate),
592                                       [this](webrtc::RTCError error) {
593                                         if (!error.ok()) {
594                                           LogAndReplyError(error.message());
595                                         }
596                                       });
597   } else {
598     LogAndReplyError("Unknown client message type: " + type);
599     return;
600   }
601 }
602 
Close()603 void ClientHandler::Close() {
604   // We can't simply call peer_connection_->Close() here because this method
605   // could be called from one of the PeerConnectionObserver callbacks and that
606   // would lead to a deadlock (Close eventually tries to destroy an object that
607   // will then wait for the callback to return -> deadlock). Destroying the
608   // peer_connection_ has the same effect. The only alternative is to postpone
609   // that operation until after the callback returns.
610   on_connection_closed_cb_();
611 }
612 
OnConnectionChange(webrtc::PeerConnectionInterface::PeerConnectionState new_state)613 void ClientHandler::OnConnectionChange(
614     webrtc::PeerConnectionInterface::PeerConnectionState new_state) {
615   switch (new_state) {
616     case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
617       break;
618     case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
619       break;
620     case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
621       LOG(VERBOSE) << "Client " << client_id_ << ": WebRTC connected";
622       state_ = State::kConnected;
623       observer_->OnConnected(
624           [this](const uint8_t *msg, size_t size, bool binary) {
625             control_handler_->Send(msg, size, binary);
626             return true;
627           });
628       break;
629     case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
630       LOG(VERBOSE) << "Client " << client_id_ << ": Connection disconnected";
631       Close();
632       break;
633     case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
634       LOG(ERROR) << "Client " << client_id_ << ": Connection failed";
635       Close();
636       break;
637     case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
638       LOG(VERBOSE) << "Client " << client_id_ << ": Connection closed";
639       Close();
640       break;
641   }
642 }
643 
OnIceCandidate(const webrtc::IceCandidateInterface * candidate)644 void ClientHandler::OnIceCandidate(
645     const webrtc::IceCandidateInterface *candidate) {
646   std::string candidate_sdp;
647   candidate->ToString(&candidate_sdp);
648   auto sdp_mid = candidate->sdp_mid();
649   auto line_index = candidate->sdp_mline_index();
650 
651   Json::Value reply;
652   reply["type"] = "ice-candidate";
653   reply["mid"] = sdp_mid;
654   reply["mLineIndex"] = static_cast<Json::UInt64>(line_index);
655   reply["candidate"] = candidate_sdp;
656 
657   send_to_client_(reply);
658 }
659 
OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel)660 void ClientHandler::OnDataChannel(
661     rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
662   auto label = data_channel->label();
663   if (label == kInputChannelLabel) {
664     input_handler_.reset(new InputChannelHandler(data_channel, observer_));
665   } else if (label == kAdbChannelLabel) {
666     adb_handler_.reset(new AdbChannelHandler(data_channel, observer_));
667   } else if (label == kBluetoothChannelLabel) {
668     bluetooth_handler_.reset(
669         new BluetoothChannelHandler(data_channel, observer_));
670   } else {
671     LOG(VERBOSE) << "Data channel connected: " << label;
672     data_channels_.push_back(data_channel);
673   }
674 }
675 
OnRenegotiationNeeded()676 void ClientHandler::OnRenegotiationNeeded() {
677   state_ = State::kNew;
678   LOG(VERBOSE) << "Client " << client_id_ << " needs renegotiation";
679 }
680 
OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state)681 void ClientHandler::OnIceGatheringChange(
682     webrtc::PeerConnectionInterface::IceGatheringState new_state) {
683   std::string state_str;
684   switch (new_state) {
685     case webrtc::PeerConnectionInterface::IceGatheringState::kIceGatheringNew:
686       state_str = "NEW";
687       break;
688     case webrtc::PeerConnectionInterface::IceGatheringState::
689         kIceGatheringGathering:
690       state_str = "GATHERING";
691       break;
692     case webrtc::PeerConnectionInterface::IceGatheringState::
693         kIceGatheringComplete:
694       state_str = "COMPLETE";
695       break;
696     default:
697       state_str = "UNKNOWN";
698   }
699   LOG(VERBOSE) << "Client " << client_id_
700                << ": ICE Gathering state set to: " << state_str;
701 }
702 
OnIceCandidateError(const std::string & host_candidate,const std::string & url,int error_code,const std::string & error_text)703 void ClientHandler::OnIceCandidateError(const std::string &host_candidate,
704                                         const std::string &url, int error_code,
705                                         const std::string &error_text) {
706   LOG(VERBOSE) << "Gathering of an ICE candidate (host candidate: "
707                << host_candidate << ", url: " << url
708                << ") failed: " << error_text;
709 }
710 
OnIceCandidateError(const std::string & address,int port,const std::string & url,int error_code,const std::string & error_text)711 void ClientHandler::OnIceCandidateError(const std::string &address, int port,
712                                         const std::string &url, int error_code,
713                                         const std::string &error_text) {
714   LOG(VERBOSE) << "Gathering of an ICE candidate (address: " << address
715                << ", port: " << port << ", url: " << url
716                << ") failed: " << error_text;
717 }
718 
OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state)719 void ClientHandler::OnSignalingChange(
720     webrtc::PeerConnectionInterface::SignalingState new_state) {
721   // ignore
722 }
OnStandardizedIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state)723 void ClientHandler::OnStandardizedIceConnectionChange(
724     webrtc::PeerConnectionInterface::IceConnectionState new_state) {
725   switch (new_state) {
726     case webrtc::PeerConnectionInterface::kIceConnectionNew:
727       LOG(DEBUG) << "ICE connection state: New";
728       break;
729     case webrtc::PeerConnectionInterface::kIceConnectionChecking:
730       LOG(DEBUG) << "ICE connection state: Checking";
731       break;
732     case webrtc::PeerConnectionInterface::kIceConnectionConnected:
733       LOG(DEBUG) << "ICE connection state: Connected";
734       break;
735     case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
736       LOG(DEBUG) << "ICE connection state: Completed";
737       break;
738     case webrtc::PeerConnectionInterface::kIceConnectionFailed:
739       state_ = State::kFailed;
740       LOG(DEBUG) << "ICE connection state: Failed";
741       break;
742     case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
743       LOG(DEBUG) << "ICE connection state: Disconnected";
744       break;
745     case webrtc::PeerConnectionInterface::kIceConnectionClosed:
746       LOG(DEBUG) << "ICE connection state: Closed";
747       break;
748     case webrtc::PeerConnectionInterface::kIceConnectionMax:
749       LOG(DEBUG) << "ICE connection state: Max";
750       break;
751   }
752 }
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)753 void ClientHandler::OnIceCandidatesRemoved(
754     const std::vector<cricket::Candidate> &candidates) {
755   // ignore
756 }
OnTrack(rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver)757 void ClientHandler::OnTrack(
758     rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver) {
759   // ignore
760 }
OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)761 void ClientHandler::OnRemoveTrack(
762     rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) {
763   // ignore
764 }
765 
766 }  // namespace webrtc_streaming
767 }  // namespace cuttlefish
768