aboutsummaryrefslogtreecommitdiff
path: root/host/frontend/vnc_server/vnc_client_connection.h
blob: 9f4fb96bc8a001929bf8bc757ad4adaacad2e95b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#pragma once

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "common/libs/fs/shared_fd.h"
#include "common/libs/threads/thread_annotations.h"

#include <cstdint>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

#include "common/libs/tcp_socket/tcp_socket.h"
#include "host/frontend/vnc_server/blackboard.h"
#include "host/frontend/vnc_server/virtual_inputs.h"
#include "host/frontend/vnc_server/vnc_utils.h"

namespace cvd {
namespace vnc {

class VncClientConnection {
 public:
  VncClientConnection(ClientSocket client,
                      std::shared_ptr<VirtualInputs> virtual_inputs,
                      BlackBoard* bb, bool aggressive);
  VncClientConnection(const VncClientConnection&) = delete;
  VncClientConnection& operator=(const VncClientConnection&) = delete;
  ~VncClientConnection();

  void StartSession();

 private:
  struct PixelFormat {
    std::uint8_t bits_per_pixel;
    std::uint8_t depth;
    std::uint8_t big_endian;
    std::uint8_t true_color;
    std::uint16_t red_max;
    std::uint16_t green_max;
    std::uint16_t blue_max;
    std::uint8_t red_shift;
    std::uint8_t green_shift;
    std::uint8_t blue_shift;
  };

  struct FrameBufferUpdateRequest {
    bool incremental;
    std::uint16_t x_pos;
    std::uint16_t y_pos;
    std::uint16_t width;
    std::uint16_t height;
  };

  friend bool operator==(const FrameBufferUpdateRequest&,
                         const FrameBufferUpdateRequest&);
  friend bool operator!=(const FrameBufferUpdateRequest&,
                         const FrameBufferUpdateRequest&);

  bool closed();
  void SetupProtocol();
  void SetupSecurityType();

  void GetClientInit();

  void SendServerInit() EXCLUDES(m_);
  static Message MakeFrameBufferUpdateHeader(std::uint16_t num_stripes);

  static void AppendRawStripeHeader(Message* frame_buffer_update,
                                    const Stripe& stripe);
  void AppendRawStripe(Message* frame_buffer_update, const Stripe& stripe) const
      REQUIRES(m_);
  Message MakeRawFrameBufferUpdate(const StripePtrVec& stripes) const
      REQUIRES(m_);

  static void AppendJpegSize(Message* frame_buffer_update, size_t jpeg_size);
  static void AppendJpegStripeHeader(Message* frame_buffer_update,
                                     const Stripe& stripe);
  static void AppendJpegStripe(Message* frame_buffer_update,
                               const Stripe& stripe);
  static Message MakeJpegFrameBufferUpdate(const StripePtrVec& stripes);

  Message MakeFrameBufferUpdate(const StripePtrVec& frame) REQUIRES(m_);

  void FrameBufferUpdateRequestHandler(bool aggressive) EXCLUDES(m_);

  void SendDesktopSizeUpdate() REQUIRES(m_);

  bool IsUrgent(const FrameBufferUpdateRequest& update_request) const;
  static StripeSeqNumber MostRecentStripeSeqNumber(const StripePtrVec& stripes);

  void HandleFramebufferUpdateRequest() EXCLUDES(m_);

  void HandleSetEncodings();

  void HandleSetPixelFormat();

  void HandlePointerEvent() EXCLUDES(m_);

  void UpdateAccelerometer(float x, float y, float z);

  struct Coordinates {
    float x;
    float y;
    float z;
  };

  Coordinates CoordinatesForOrientation(ScreenOrientation orientation) const;

  int ScreenWidth() const REQUIRES(m_);

  int ScreenHeight() const REQUIRES(m_);

  void SetScreenOrientation(ScreenOrientation orientation) EXCLUDES(m_);

  // Returns true if key is special and the screen was rotated.
  bool RotateIfIsRotationCommand(std::uint32_t key);

  void HandleKeyEvent();

  void HandleClientCutText();

  void NormalSession();

  mutable std::mutex m_;
  ClientSocket client_;
  bool control_key_down_ = false;
  bool meta_key_down_ = false;
  std::shared_ptr<VirtualInputs> virtual_inputs_{};

  FrameBufferUpdateRequest previous_update_request_{};
  BlackBoard* bb_;
  bool use_jpeg_compression_ GUARDED_BY(m_) = false;

  std::thread frame_buffer_request_handler_tid_;
  bool closed_ GUARDED_BY(m_){};

  PixelFormat pixel_format_ GUARDED_BY(m_) = {
      std::uint8_t{32},  // bits per pixel
      std::uint8_t{24},   // depth
      std::uint8_t{0},    // big_endian
      std::uint8_t{1},    // true_color
      std::uint16_t{0xff},   // red_max, (maxes not used when true color flag is 0)
      std::uint16_t{0xff},   // green_max
      std::uint16_t{0xff},   // blue_max
      std::uint8_t{0},  // red_shift (shifts not used when true color flag is 0)
      std::uint8_t{8},  // green_shift
      std::uint8_t{16},  // blue_shift
  };

  bool supports_desktop_size_encoding_ = false;
  ScreenOrientation current_orientation_ GUARDED_BY(m_) =
      ScreenOrientation::Portrait;

  bool client_is_old_ = false;
};

}  // namespace vnc
}  // namespace cvd