1 #pragma once
2 
3 /*
4  * Copyright (C) 2017 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include "common/libs/fs/shared_fd.h"
20 #include "common/libs/threads/thread_annotations.h"
21 
22 #include <cstdint>
23 #include <memory>
24 #include <mutex>
25 #include <thread>
26 #include <vector>
27 
28 #include "common/libs/tcp_socket/tcp_socket.h"
29 #include "host/frontend/vnc_server/blackboard.h"
30 #include "host/frontend/vnc_server/virtual_inputs.h"
31 #include "host/frontend/vnc_server/vnc_utils.h"
32 
33 namespace cuttlefish {
34 namespace vnc {
35 
36 class VncClientConnection {
37  public:
38   VncClientConnection(ClientSocket client,
39                       std::shared_ptr<VirtualInputs> virtual_inputs,
40                       BlackBoard* bb, bool aggressive);
41   VncClientConnection(const VncClientConnection&) = delete;
42   VncClientConnection& operator=(const VncClientConnection&) = delete;
43   ~VncClientConnection();
44 
45   void StartSession();
46 
47  private:
48   struct PixelFormat {
49     std::uint8_t bits_per_pixel;
50     std::uint8_t depth;
51     std::uint8_t big_endian;
52     std::uint8_t true_color;
53     std::uint16_t red_max;
54     std::uint16_t green_max;
55     std::uint16_t blue_max;
56     std::uint8_t red_shift;
57     std::uint8_t green_shift;
58     std::uint8_t blue_shift;
59   };
60 
61   struct FrameBufferUpdateRequest {
62     bool incremental;
63     std::uint16_t x_pos;
64     std::uint16_t y_pos;
65     std::uint16_t width;
66     std::uint16_t height;
67   };
68 
69   friend bool operator==(const FrameBufferUpdateRequest&,
70                          const FrameBufferUpdateRequest&);
71   friend bool operator!=(const FrameBufferUpdateRequest&,
72                          const FrameBufferUpdateRequest&);
73 
74   bool closed();
75   void SetupProtocol();
76   void SetupSecurityType();
77 
78   void GetClientInit();
79 
80   void SendServerInit() EXCLUDES(m_);
81   static Message MakeFrameBufferUpdateHeader(std::uint16_t num_stripes);
82 
83   static void AppendRawStripeHeader(Message* frame_buffer_update,
84                                     const Stripe& stripe);
85   void AppendRawStripe(Message* frame_buffer_update, const Stripe& stripe) const
86       REQUIRES(m_);
87   Message MakeRawFrameBufferUpdate(const StripePtrVec& stripes) const
88       REQUIRES(m_);
89 
90   static void AppendJpegSize(Message* frame_buffer_update, size_t jpeg_size);
91   static void AppendJpegStripeHeader(Message* frame_buffer_update,
92                                      const Stripe& stripe);
93   static void AppendJpegStripe(Message* frame_buffer_update,
94                                const Stripe& stripe);
95   static Message MakeJpegFrameBufferUpdate(const StripePtrVec& stripes);
96 
97   Message MakeFrameBufferUpdate(const StripePtrVec& frame) REQUIRES(m_);
98 
99   void FrameBufferUpdateRequestHandler(bool aggressive) EXCLUDES(m_);
100 
101   void SendDesktopSizeUpdate() REQUIRES(m_);
102 
103   bool IsUrgent(const FrameBufferUpdateRequest& update_request) const;
104   static StripeSeqNumber MostRecentStripeSeqNumber(const StripePtrVec& stripes);
105 
106   void HandleFramebufferUpdateRequest() EXCLUDES(m_);
107 
108   void HandleSetEncodings();
109 
110   void HandleSetPixelFormat();
111 
112   void HandlePointerEvent() EXCLUDES(m_);
113 
114   void UpdateAccelerometer(float x, float y, float z);
115 
116   struct Coordinates {
117     float x;
118     float y;
119     float z;
120   };
121 
122   Coordinates CoordinatesForOrientation(ScreenOrientation orientation) const;
123 
124   int ScreenWidth() const REQUIRES(m_);
125 
126   int ScreenHeight() const REQUIRES(m_);
127 
128   void SetScreenOrientation(ScreenOrientation orientation) EXCLUDES(m_);
129 
130   // Returns true if key is special and the screen was rotated.
131   bool RotateIfIsRotationCommand(std::uint32_t key);
132 
133   void HandleKeyEvent();
134 
135   void HandleClientCutText();
136 
137   void NormalSession();
138 
139   mutable std::mutex m_;
140   ClientSocket client_;
141   bool control_key_down_ = false;
142   bool meta_key_down_ = false;
143   std::shared_ptr<VirtualInputs> virtual_inputs_{};
144 
145   FrameBufferUpdateRequest previous_update_request_{};
146   BlackBoard* bb_;
147   bool use_jpeg_compression_ GUARDED_BY(m_) = false;
148 
149   std::thread frame_buffer_request_handler_tid_;
GUARDED_BY(m_)150   bool closed_ GUARDED_BY(m_){};
151 
152   PixelFormat pixel_format_ GUARDED_BY(m_) = {
153       std::uint8_t{32},  // bits per pixel
154       std::uint8_t{24},   // depth
155       std::uint8_t{0},    // big_endian
156       std::uint8_t{1},    // true_color
157       std::uint16_t{0xff},   // red_max, (maxes not used when true color flag is 0)
158       std::uint16_t{0xff},   // green_max
159       std::uint16_t{0xff},   // blue_max
160       std::uint8_t{0},  // red_shift (shifts not used when true color flag is 0)
161       std::uint8_t{8},  // green_shift
162       std::uint8_t{16},  // blue_shift
163   };
164 
165   bool supports_desktop_size_encoding_ = false;
166   ScreenOrientation current_orientation_ GUARDED_BY(m_) =
167       ScreenOrientation::Portrait;
168 
169   bool client_is_old_ = false;
170 };
171 
172 }  // namespace vnc
173 }  // namespace cuttlefish
174