• 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 #include "host/frontend/webrtc_operator/client_handler.h"
17 
18 #include <android-base/logging.h>
19 
20 #include "host/frontend/webrtc_operator/constants/signaling_constants.h"
21 #include "host/frontend/webrtc_operator/device_handler.h"
22 
23 namespace cuttlefish {
24 
ClientHandler(struct lws * wsi,DeviceRegistry * registry,const ServerConfig & server_config)25 ClientHandler::ClientHandler(struct lws* wsi, DeviceRegistry* registry,
26                              const ServerConfig& server_config)
27     : SignalHandler(wsi, registry, server_config),
28       device_handler_(),
29       client_id_(0) {}
30 
OnClosed()31 void ClientHandler::OnClosed() {
32   auto device_handler = device_handler_.lock();
33   if (device_handler) {
34     device_handler->SendClientDisconnectMessage(client_id_);
35   }
36 }
37 
SendDeviceMessage(const Json::Value & device_message)38 void ClientHandler::SendDeviceMessage(const Json::Value& device_message) {
39   Json::Value message;
40   message[webrtc_signaling::kTypeField] = webrtc_signaling::kDeviceMessageType;
41   message[webrtc_signaling::kPayloadField] = device_message;
42   Reply(message);
43 }
44 
handleMessage(const std::string & type,const Json::Value & message)45 void ClientHandler::handleMessage(const std::string& type,
46                                   const Json::Value& message) {
47   if (type == webrtc_signaling::kConnectType) {
48     handleConnectionRequest(message);
49   } else if (type == webrtc_signaling::kForwardType) {
50     handleForward(message);
51   } else {
52     LogAndReplyError("Unknown message type: " + type);
53   }
54 }
55 
handleConnectionRequest(const Json::Value & message)56 void ClientHandler::handleConnectionRequest(const Json::Value& message) {
57   if (client_id_ > 0) {
58     LogAndReplyError(
59         "Attempt to connect to multiple devices over same websocket");
60     Close();
61     return;
62   }
63   if (!message.isMember(webrtc_signaling::kDeviceIdField) ||
64       !message[webrtc_signaling::kDeviceIdField].isString()) {
65     LogAndReplyError("Invalid connection request: Missing device id");
66     Close();
67     return;
68   }
69   auto device_id = message[webrtc_signaling::kDeviceIdField].asString();
70   // Always send the server config back, even if the requested device is not
71   // registered. Applications may put clients on hold until the device is ready
72   // to connect.
73   SendServerConfig();
74 
75   auto device_handler = registry_->GetDevice(device_id);
76   if (!device_handler) {
77     LogAndReplyError("Connection failed: Device not found: '" + device_id +
78                      "'");
79     Close();
80     return;
81   }
82 
83   client_id_ = device_handler->RegisterClient(shared_from_this());
84   device_handler_ = device_handler;
85   Json::Value device_info_reply;
86   device_info_reply[webrtc_signaling::kTypeField] =
87       webrtc_signaling::kDeviceInfoType;
88   device_info_reply[webrtc_signaling::kDeviceInfoField] =
89       device_handler->device_info();
90   Reply(device_info_reply);
91 }
92 
handleForward(const Json::Value & message)93 void ClientHandler::handleForward(const Json::Value& message) {
94   if (client_id_ == 0) {
95     LogAndReplyError("Forward failed: No device asociated to client");
96     Close();
97     return;
98   }
99   if (!message.isMember(webrtc_signaling::kPayloadField)) {
100     LogAndReplyError("Forward failed: No payload present in message");
101     Close();
102     return;
103   }
104   auto device_handler = device_handler_.lock();
105   if (!device_handler) {
106     LogAndReplyError("Forward failed: Device disconnected");
107     // Disconnect this client since the device is gone
108     Close();
109     return;
110   }
111   device_handler->SendClientMessage(client_id_,
112                                     message[webrtc_signaling::kPayloadField]);
113 }
114 
ClientHandlerFactory(DeviceRegistry * registry,const ServerConfig & server_config)115 ClientHandlerFactory::ClientHandlerFactory(DeviceRegistry* registry,
116                                            const ServerConfig& server_config)
117   : registry_(registry),
118     server_config_(server_config) {}
119 
Build(struct lws * wsi)120 std::shared_ptr<WebSocketHandler> ClientHandlerFactory::Build(struct lws* wsi) {
121   return std::shared_ptr<WebSocketHandler>(
122       new ClientHandler(wsi, registry_, server_config_));
123 }
124 
125 }  // namespace cuttlefish
126