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 #pragma once
17 
18 #include <memory>
19 #include <string>
20 
21 #include <json/json.h>
22 
23 #include "host/frontend/webrtc_operator/device_registry.h"
24 #include "host/frontend/webrtc_operator/server_config.h"
25 #include "host/frontend/webrtc_operator/signal_handler.h"
26 #include "host/libs/websocket/websocket_handler.h"
27 
28 namespace cuttlefish {
29 class DeviceHandler;
30 
31 class ClientHandler {
32  public:
33   virtual ~ClientHandler() = default;
34   virtual void SendDeviceMessage(const Json::Value& message) = 0;
35 };
36 
37 class ClientWSHandler : public ClientHandler,
38                         public SignalHandler,
39                         public std::enable_shared_from_this<ClientHandler> {
40  public:
41   ClientWSHandler(struct lws* wsi, DeviceRegistry* registry,
42                   const ServerConfig& server_config);
43 
44   void SendDeviceMessage(const Json::Value& message) override;
45 
46   void OnClosed() override;
47 
48  protected:
49   void handleMessage(const std::string& type,
50                      const Json::Value& message) override;
51 
52  private:
53   void handleConnectionRequest(const Json::Value& message);
54   void handleForward(const Json::Value& message);
55 
56   std::weak_ptr<DeviceHandler> device_handler_;
57   // The device handler assigns this to each client to be able to differentiate
58   // them.
59   size_t client_id_;
60 };
61 
62 class ClientWSHandlerFactory : public WebSocketHandlerFactory {
63  public:
64   ClientWSHandlerFactory(DeviceRegistry* registry,
65                          const ServerConfig& server_config);
66   std::shared_ptr<WebSocketHandler> Build(struct lws* wsi) override;
67 
68  private:
69   DeviceRegistry* registry_;
70   const ServerConfig& server_config_;
71 };
72 
73 class PollConnectionHandler;
74 
75 class PollConnectionStore {
76   public:
77     PollConnectionStore() = default;
78 
79     std::shared_ptr<PollConnectionHandler> Get(const std::string& conn_id) const;
80     std::string Add(std::shared_ptr<PollConnectionHandler> handler);
81   private:
82    std::map<std::string, std::shared_ptr<PollConnectionHandler>>
83        handlers_;
84 };
85 
86 class ClientDynHandler : public DynHandler,
87                          public std::enable_shared_from_this<ClientHandler> {
88  public:
89   ClientDynHandler(struct lws* wsi, PollConnectionStore* poll_store);
90 
91   HttpStatusCode DoGet() override;
92   HttpStatusCode DoPost() override;
93 
94  protected:
95   virtual HttpStatusCode DoPostInner(std::shared_ptr<PollConnectionHandler>,
96                                      const Json::Value&) = 0;
97   // In the base class because it's shared by some of the subclasses
98   HttpStatusCode Poll(std::shared_ptr<PollConnectionHandler>);
99 
100   void Reply(const Json::Value& json);
101   void ReplyError(const std::string& message);
102   bool ParseInput();
103 
104   PollConnectionStore* poll_store_;
105 };
106 
107 class ConnectHandler : public ClientDynHandler {
108  public:
109   ConnectHandler(struct lws* wsi, DeviceRegistry* registry,
110                  PollConnectionStore* poll_store);
111 
112  protected:
113   HttpStatusCode DoPostInner(std::shared_ptr<PollConnectionHandler>,
114                              const Json::Value&) override;
115  private:
116   DeviceRegistry* registry_;
117 };
118 
119 class ForwardHandler : public ClientDynHandler {
120  public:
121   ForwardHandler(struct lws* wsi, PollConnectionStore* poll_store);
122 
123  protected:
124   HttpStatusCode DoPostInner(std::shared_ptr<PollConnectionHandler>,
125                              const Json::Value&) override;
126 };
127 
128 class PollHandler : public ClientDynHandler {
129  public:
130   PollHandler(struct lws* wsi, PollConnectionStore* poll_store);
131 
132  protected:
133   HttpStatusCode DoPostInner(std::shared_ptr<PollConnectionHandler>,
134                              const Json::Value&) override;
135 };
136 
137 class ConfigHandler : public DynHandler {
138  public:
139   ConfigHandler(struct lws* wsi, const ServerConfig& server_config);
140 
141   HttpStatusCode DoGet() override;
142 
143   HttpStatusCode DoPost() override;
144 
145  private:
146   const ServerConfig& server_config_;
147 };
148 
149 }  // namespace cuttlefish
150