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