Switches to host side vnc
It builds as a host side binary that's launched by launch_cvd.
Bug: 70945014
Bug: 65062047
Test: run locally
Change-Id: I4aaac15f0ba11c7ab026c441afe0b3eb0b2665f5
diff --git a/guest/frontend/vnc_server/Android.mk b/guest/frontend/vnc_server/Android.mk
deleted file mode 100644
index 4b008f3..0000000
--- a/guest/frontend/vnc_server/Android.mk
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (C) 2016 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.
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-
-ifneq (,$(filter $(PLATFORM_SDK_VERSION),16 17 18 19 21 22 23)) # J K L M
- # prior to (not including) nyc, libjpeg was used instead of libjpeg turbo
- # the libjpeg turbo in external/ is a backport with the shared library name
- # changed to libjpeg_turbo to avoid conflict with the system's libjpeg
- LIBJPEG_TURBO_NAME := libjpeg_turbo
-else
- # nyc and later use libjpeg turbo under its usual name
- LIBJPEG_TURBO_NAME := libjpeg
-endif
-
-LOCAL_C_INCLUDES := \
- device/google/cuttlefish_common \
- device/google/cuttlefish_kernel \
- external/libjpeg-turbo \
- external/jsoncpp/include
-
-LOCAL_MODULE := vnc_server
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
- blackboard.cpp \
- frame_buffer_watcher.cpp \
- jpeg_compressor.cpp \
- main.cpp \
- simulated_hw_composer.cpp \
- virtual_inputs.cpp \
- vnc_client_connection.cpp \
- vnc_server.cpp \
-
-LOCAL_CFLAGS := \
- $(VSOC_VERSION_CFLAGS) \
- -std=gnu++11 \
- -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
- $(LIBJPEG_TURBO_NAME) \
- libbase \
- liblog \
- libutils \
- libcutils \
- cuttlefish_auto_resources \
- cuttlefish_tcp_socket \
- libcuttlefish_fs \
- vsoc_lib
-
-LOCAL_STATIC_LIBRARIES := \
- libjsoncpp
-
-include $(BUILD_EXECUTABLE)
diff --git a/guest/frontend/vnc_server/blackboard.cpp b/guest/frontend/vnc_server/blackboard.cpp
deleted file mode 100644
index b28e399..0000000
--- a/guest/frontend/vnc_server/blackboard.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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 "blackboard.h"
-#include "frame_buffer_watcher.h"
-#include <utility>
-#include <algorithm>
-
-#define LOG_TAG ""
-#include <cutils/log.h>
-
-using cvd::vnc::BlackBoard;
-using cvd::vnc::Stripe;
-
-cvd::vnc::SeqNumberVec cvd::vnc::MakeSeqNumberVec() {
- return SeqNumberVec(FrameBufferWatcher::StripesPerFrame());
-}
-
-void BlackBoard::NewStripeReady(int index, StripeSeqNumber seq_num) {
- std::lock_guard<std::mutex> guard(m_);
- D("new stripe arrived from frame watcher");
- auto& current_seq_num = most_recent_stripe_seq_nums_[index];
- current_seq_num = std::max(current_seq_num, seq_num);
- for (auto& client : clients_) {
- if (client.second.ready_to_receive) {
- client.second.new_frame_cv.notify_one();
- }
- }
-}
-
-void BlackBoard::Register(const VncClientConnection* conn) {
- {
- std::lock_guard<std::mutex> guard(m_);
- ALOG_ASSERT(!clients_.count(conn));
- clients_[conn]; // constructs new state in place
- }
- new_client_cv_.notify_one();
-}
-
-void BlackBoard::Unregister(const VncClientConnection* conn) {
- std::lock_guard<std::mutex> guard(m_);
- ALOG_ASSERT(clients_.count(conn));
- clients_.erase(clients_.find(conn));
-}
-
-bool BlackBoard::NoNewStripesFor(const SeqNumberVec& seq_nums) const {
- ALOG_ASSERT(seq_nums.size() == most_recent_stripe_seq_nums.size());
- for (auto state_seq_num = seq_nums.begin(),
- held_seq_num = most_recent_stripe_seq_nums_.begin();
- state_seq_num != seq_nums.end(); ++state_seq_num, ++held_seq_num) {
- if (*state_seq_num < *held_seq_num) {
- return false;
- }
- }
- return true;
-}
-
-cvd::vnc::StripePtrVec BlackBoard::WaitForSenderWork(
- const VncClientConnection* conn) {
- std::unique_lock<std::mutex> guard(m_);
- auto& state = GetStateForClient(conn);
- D("Waiting for stripe...");
- while (!state.closed &&
- (!state.ready_to_receive || NoNewStripesFor(state.stripe_seq_nums))) {
- state.new_frame_cv.wait(guard);
- }
- D("At least one new stripe is available, should unblock %p", conn);
- state.ready_to_receive = false;
- auto new_stripes = frame_buffer_watcher_->StripesNewerThan(
- state.orientation, state.stripe_seq_nums);
- for (auto& s : new_stripes) {
- state.stripe_seq_nums[s->index] = s->seq_number;
- }
- return new_stripes;
-}
-
-void BlackBoard::WaitForAtLeastOneClientConnection() {
- std::unique_lock<std::mutex> guard(m_);
- while (clients_.empty()) {
- new_client_cv_.wait(guard);
- }
-}
-
-void BlackBoard::SetOrientation(const VncClientConnection* conn,
- ScreenOrientation orientation) {
- std::lock_guard<std::mutex> guard(m_);
- auto& state = GetStateForClient(conn);
- state.orientation = orientation;
- // After an orientation change the vnc client will need all stripes from
- // the new orientation, regardless of age.
- ResetToZero(&state.stripe_seq_nums);
-}
-
-void BlackBoard::SignalClientNeedsEntireScreen(
- const VncClientConnection* conn) {
- std::lock_guard<std::mutex> guard(m_);
- ResetToZero(&GetStateForClient(conn).stripe_seq_nums);
-}
-
-void BlackBoard::ResetToZero(SeqNumberVec* seq_nums) {
- seq_nums->assign(FrameBufferWatcher::StripesPerFrame(), StripeSeqNumber{});
-}
-
-void BlackBoard::FrameBufferUpdateRequestReceived(
- const VncClientConnection* conn) {
- std::lock_guard<std::mutex> guard(m_);
- D("Received frame buffer update request");
- auto& state = GetStateForClient(conn);
- state.ready_to_receive = true;
- state.new_frame_cv.notify_one();
-}
-
-void BlackBoard::StopWaiting(const VncClientConnection* conn) {
- std::lock_guard<std::mutex> guard(m_);
- auto& state = GetStateForClient(conn);
- state.closed = true;
- // Wake up the thread that might be in WaitForSenderWork()
- state.new_frame_cv.notify_one();
-}
-
-void BlackBoard::set_frame_buffer_watcher(
- cvd::vnc::FrameBufferWatcher* frame_buffer_watcher) {
- std::lock_guard<std::mutex> guard(m_);
- frame_buffer_watcher_ = frame_buffer_watcher;
-}
-
-void BlackBoard::set_jpeg_quality_level(int quality_level) {
- // NOTE all vnc clients share a common jpeg quality level because the
- // server doesn't compress per-client. The quality level for all clients
- // will be whatever the most recent set was by any client.
- std::lock_guard<std::mutex> guard(m_);
- if (quality_level < kJpegMinQualityEncoding ||
- quality_level > kJpegMaxQualityEncoding) {
- ALOGW("Bogus jpeg quality level: %d. Quality must be in range [%d, %d]",
- quality_level, kJpegMinQualityEncoding, kJpegMaxQualityEncoding);
- return;
- }
- jpeg_quality_level_ = 55 + (5 * (quality_level + 32));
- D("jpeg quality level set to %d%%:", jpeg_quality_level_);
-}
-
-BlackBoard::ClientFBUState& BlackBoard::GetStateForClient(
- const VncClientConnection* conn) {
- ALOG_ASSERT(clients_.count(conn));
- return clients_[conn];
-}
diff --git a/guest/frontend/vnc_server/blackboard.h b/guest/frontend/vnc_server/blackboard.h
deleted file mode 100644
index dfd9257..0000000
--- a/guest/frontend/vnc_server/blackboard.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#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 "vnc_utils.h"
-
-#include <android-base/thread_annotations.h>
-
-#include <unordered_map>
-#include <mutex>
-#include <condition_variable>
-#include <memory>
-
-namespace cvd {
-namespace vnc {
-
-class VncClientConnection;
-class FrameBufferWatcher;
-using StripePtrVec = std::vector<std::shared_ptr<const Stripe>>;
-using SeqNumberVec = std::vector<StripeSeqNumber>;
-
-SeqNumberVec MakeSeqNumberVec();
-
-class BlackBoard {
- private:
- struct ClientFBUState {
- bool ready_to_receive{};
- ScreenOrientation orientation{};
- std::condition_variable new_frame_cv;
- SeqNumberVec stripe_seq_nums = MakeSeqNumberVec();
- bool closed{};
- };
-
- public:
- class Registerer {
- public:
- Registerer(BlackBoard* bb, const VncClientConnection* conn)
- : bb_{bb}, conn_{conn} {
- bb->Register(conn);
- }
- ~Registerer() {
- bb_->Unregister(conn_);
- }
- Registerer(const Registerer&) = delete;
- Registerer& operator=(const Registerer&) = delete;
-
- private:
- BlackBoard* bb_{};
- const VncClientConnection* conn_{};
- };
-
- BlackBoard() = default;
- BlackBoard(const BlackBoard&) = delete;
- BlackBoard& operator=(const BlackBoard&) = delete;
-
- bool NoNewStripesFor(const SeqNumberVec& seq_nums) const REQUIRES(m_);
- void NewStripeReady(int index, StripeSeqNumber seq_num);
- void Register(const VncClientConnection* conn);
- void Unregister(const VncClientConnection* conn);
-
- StripePtrVec WaitForSenderWork(const VncClientConnection* conn);
-
- void WaitForAtLeastOneClientConnection();
-
- void FrameBufferUpdateRequestReceived(const VncClientConnection* conn);
- // Setting orientation implies needing the entire screen
- void SetOrientation(const VncClientConnection* conn,
- ScreenOrientation orientation);
- void SignalClientNeedsEntireScreen(const VncClientConnection* conn);
-
- void StopWaiting(const VncClientConnection* conn);
-
- void set_frame_buffer_watcher(FrameBufferWatcher* frame_buffer_watcher);
-
- // quality_level must be the value received from the client, in the range
- // [kJpegMinQualityEncoding, kJpegMaxQualityEncoding], else it is ignored.
- void set_jpeg_quality_level(int quality_level);
-
- int jpeg_quality_level() const {
- std::lock_guard<std::mutex> guard(m_);
- return jpeg_quality_level_;
- }
-
- private:
- ClientFBUState& GetStateForClient(const VncClientConnection* conn)
- REQUIRES(m_);
- static void ResetToZero(SeqNumberVec* seq_nums);
-
- mutable std::mutex m_;
- SeqNumberVec most_recent_stripe_seq_nums_ GUARDED_BY(m_) = MakeSeqNumberVec();
- std::unordered_map<const VncClientConnection*, ClientFBUState> clients_
- GUARDED_BY(m_);
- int jpeg_quality_level_ GUARDED_BY(m_) = 100;
- std::condition_variable new_client_cv_;
- // NOTE the FrameBufferWatcher pointer itself should be
- // guarded, but not the pointee.
- FrameBufferWatcher* frame_buffer_watcher_ GUARDED_BY(m_){};
-};
-
-} // namespace vnc
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/frame_buffer_watcher.cpp b/guest/frontend/vnc_server/frame_buffer_watcher.cpp
deleted file mode 100644
index 5f68748..0000000
--- a/guest/frontend/vnc_server/frame_buffer_watcher.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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 "vnc_utils.h"
-#include "frame_buffer_watcher.h"
-#include <common/libs/thread_safe_queue/thread_safe_queue.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <iterator>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <utility>
-
-#define LOG_TAG ""
-#include <cutils/log.h>
-
-using cvd::vnc::FrameBufferWatcher;
-
-FrameBufferWatcher::FrameBufferWatcher(BlackBoard* bb)
- : bb_{bb}, hwcomposer{bb_} {
- for (auto& stripes_vec : stripes_) {
- std::generate_n(std::back_inserter(stripes_vec),
- SimulatedHWComposer::NumberOfStripes(),
- std::make_shared<Stripe>);
- }
- bb_->set_frame_buffer_watcher(this);
- auto num_workers = std::max(std::thread::hardware_concurrency(), 1u);
- std::generate_n(std::back_inserter(workers_), num_workers, [this] {
- return std::thread{&FrameBufferWatcher::Worker, this};
- });
-}
-
-FrameBufferWatcher::~FrameBufferWatcher() {
- {
- std::lock_guard<std::mutex> guard(m_);
- closed_ = true;
- }
- for (auto& tid : workers_) {
- tid.join();
- }
-}
-
-bool FrameBufferWatcher::closed() const {
- std::lock_guard<std::mutex> guard(m_);
- return closed_;
-}
-
-cvd::vnc::Stripe FrameBufferWatcher::Rotated(Stripe stripe) {
- LOG_ALWAYS_FATAL_IF(stripe.orientation == ScreenOrientation::Landscape,
- "Rotating a landscape stripe, this is a mistake");
- auto w = stripe.width;
- auto h = stripe.height;
- const auto& raw = stripe.raw_data;
- Message rotated(raw.size(), 0xAA);
- for (std::uint16_t i = 0; i < w; ++i) {
- for (std::uint16_t j = 0; j < h; ++j) {
- auto to = (i * h + j) * BytesPerPixel();
- auto from = (w - (i + 1) + w * j) * BytesPerPixel();
- ALOG_ASSERT(from < raw.size());
- ALOG_ASSERT(to < rotated.size());
- std::memcpy(&rotated[to], &raw[from], BytesPerPixel());
- }
- }
- std::swap(stripe.x, stripe.y);
- std::swap(stripe.width, stripe.height);
- stripe.raw_data = std::move(rotated);
- stripe.orientation = ScreenOrientation::Landscape;
- return stripe;
-}
-
-bool FrameBufferWatcher::StripeIsDifferentFromPrevious(
- const Stripe& stripe) const {
- return Stripes(stripe.orientation)[stripe.index]->raw_data != stripe.raw_data;
-}
-
-cvd::vnc::StripePtrVec FrameBufferWatcher::StripesNewerThan(
- ScreenOrientation orientation, const SeqNumberVec& seq_numbers) const {
- std::lock_guard<std::mutex> guard(stripes_lock_);
- const auto& stripes = Stripes(orientation);
- ALOG_ASSERT(seq_numbers.size() == stripes.size());
- StripePtrVec new_stripes;
- auto seq_number_it = seq_numbers.begin();
- std::copy_if(stripes.begin(), stripes.end(), std::back_inserter(new_stripes),
- [seq_number_it](const StripePtrVec::value_type& s) mutable {
- return *(seq_number_it++) < s->seq_number;
- });
- return new_stripes;
-}
-
-cvd::vnc::StripePtrVec& FrameBufferWatcher::Stripes(
- ScreenOrientation orientation) {
- return stripes_[static_cast<int>(orientation)];
-}
-
-const cvd::vnc::StripePtrVec& FrameBufferWatcher::Stripes(
- ScreenOrientation orientation) const {
- return stripes_[static_cast<int>(orientation)];
-}
-
-bool FrameBufferWatcher::UpdateMostRecentSeqNumIfStripeIsNew(
- const Stripe& stripe) {
- if (most_recent_identical_stripe_seq_nums_[stripe.index] <=
- stripe.seq_number) {
- most_recent_identical_stripe_seq_nums_[stripe.index] = stripe.seq_number;
- return true;
- }
- return false;
-}
-
-bool FrameBufferWatcher::UpdateStripeIfStripeIsNew(
- const std::shared_ptr<const Stripe>& stripe) {
- std::lock_guard<std::mutex> guard(stripes_lock_);
- if (UpdateMostRecentSeqNumIfStripeIsNew(*stripe)) {
- Stripes(stripe->orientation)[stripe->index] = stripe;
- return true;
- }
- return false;
-}
-
-void FrameBufferWatcher::CompressStripe(JpegCompressor* jpeg_compressor,
- Stripe* stripe) {
- stripe->jpeg_data = jpeg_compressor->Compress(
- stripe->raw_data, bb_->jpeg_quality_level(), 0, 0, stripe->width,
- stripe->height, stripe->width);
-}
-
-void FrameBufferWatcher::Worker() {
- JpegCompressor jpeg_compressor;
-#ifdef FUZZ_TEST_VNC
- std::default_random_engine e{std::random_device{}()};
- std::uniform_int_distribution<int> random{0, 2};
-#endif
- while (!closed()) {
- auto portrait_stripe = hwcomposer.GetNewStripe();
- if (closed()) {
- break;
- }
- {
- // TODO(haining) use if (with init) and else for c++17 instead of extra
- // scope and continue
- // if (std::lock_guard guard(stripes_lock_); /*condition*/) { }
- std::lock_guard<std::mutex> guard(stripes_lock_);
- if (!StripeIsDifferentFromPrevious(portrait_stripe)) {
- UpdateMostRecentSeqNumIfStripeIsNew(portrait_stripe);
- continue;
- }
- }
- auto seq_num = portrait_stripe.seq_number;
- auto index = portrait_stripe.index;
- auto landscape_stripe = Rotated(portrait_stripe);
- auto stripes = {std::make_shared<Stripe>(std::move(portrait_stripe)),
- std::make_shared<Stripe>(std::move(landscape_stripe))};
- for (auto& stripe : stripes) {
-#ifdef FUZZ_TEST_VNC
- if (random(e)) {
- usleep(10000);
- }
-#endif
- CompressStripe(&jpeg_compressor, stripe.get());
- }
- bool any_new_stripes = false;
- for (auto& stripe : stripes) {
- any_new_stripes = UpdateStripeIfStripeIsNew(stripe) || any_new_stripes;
- }
- if (any_new_stripes) {
- bb_->NewStripeReady(index, seq_num);
- }
- }
-}
-
-int FrameBufferWatcher::StripesPerFrame() {
- return SimulatedHWComposer::NumberOfStripes();
-}
diff --git a/guest/frontend/vnc_server/frame_buffer_watcher.h b/guest/frontend/vnc_server/frame_buffer_watcher.h
deleted file mode 100644
index b678b8f..0000000
--- a/guest/frontend/vnc_server/frame_buffer_watcher.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#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 "blackboard.h"
-#include "jpeg_compressor.h"
-#include "simulated_hw_composer.h"
-
-#include <vector>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <utility>
-
-namespace cvd {
-namespace vnc {
-class FrameBufferWatcher {
- public:
- explicit FrameBufferWatcher(BlackBoard* bb);
- FrameBufferWatcher(const FrameBufferWatcher&) = delete;
- FrameBufferWatcher& operator=(const FrameBufferWatcher&) = delete;
- ~FrameBufferWatcher();
-
- StripePtrVec StripesNewerThan(ScreenOrientation orientation,
- const SeqNumberVec& seq_num) const;
- static int StripesPerFrame();
-
- private:
- static Stripe Rotated(Stripe stripe);
-
- bool closed() const;
- bool StripeIsDifferentFromPrevious(const Stripe& stripe) const
- REQUIRES(stripes_lock_);
- // returns true if stripe is still considered new and seq number was updated
- bool UpdateMostRecentSeqNumIfStripeIsNew(const Stripe& stripe)
- REQUIRES(stripes_lock_);
- // returns true if stripe is still considered new and was updated
- bool UpdateStripeIfStripeIsNew(const std::shared_ptr<const Stripe>& stripe)
- EXCLUDES(stripes_lock_);
- // Compresses stripe->raw_data to stripe->jpeg_data
- void CompressStripe(JpegCompressor* jpeg_compressor, Stripe* stripe);
- void Worker();
- void Updater();
-
- StripePtrVec& Stripes(ScreenOrientation orientation) REQUIRES(stripes_lock_);
- const StripePtrVec& Stripes(ScreenOrientation orientation) const
- REQUIRES(stripes_lock_);
-
- std::vector<std::thread> workers_;
- mutable std::mutex stripes_lock_;
- std::array<StripePtrVec, kNumOrientations> stripes_ GUARDED_BY(stripes_lock_);
- SeqNumberVec most_recent_identical_stripe_seq_nums_
- GUARDED_BY(stripes_lock_) = MakeSeqNumberVec();
- mutable std::mutex m_;
- bool closed_ GUARDED_BY(m_){};
- BlackBoard* bb_{};
- SimulatedHWComposer hwcomposer{bb_};
-};
-
-} // namespace vnc
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/jpeg_compressor.cpp b/guest/frontend/vnc_server/jpeg_compressor.cpp
deleted file mode 100644
index f0b2ca6..0000000
--- a/guest/frontend/vnc_server/jpeg_compressor.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 "jpeg_compressor.h"
-#include "vnc_utils.h"
-
-#include <stdio.h> // stdio.h must appear before jpeglib.h
-#include <jpeglib.h>
-
-#define LOG_TAG ""
-#include <cutils/log.h>
-
-using cvd::vnc::JpegCompressor;
-
-namespace {
-void InitCinfo(jpeg_compress_struct* cinfo, jpeg_error_mgr* err,
- std::uint16_t width, std::uint16_t height, int jpeg_quality) {
- cinfo->err = jpeg_std_error(err);
- jpeg_create_compress(cinfo);
-
- cinfo->image_width = width;
- cinfo->image_height = height;
- cinfo->input_components = cvd::vnc::BytesPerPixel();
- cinfo->in_color_space = JCS_EXT_RGBX;
-
- jpeg_set_defaults(cinfo);
- jpeg_set_quality(cinfo, jpeg_quality, true);
-}
-} // namespace
-
-cvd::Message JpegCompressor::Compress(const Message& frame,
- int jpeg_quality, std::uint16_t x,
- std::uint16_t y, std::uint16_t width,
- std::uint16_t height,
- int screen_width) {
- jpeg_compress_struct cinfo{};
- jpeg_error_mgr err{};
- InitCinfo(&cinfo, &err, width, height, jpeg_quality);
-
- auto* compression_buffer = buffer_.get();
- auto compression_buffer_size = buffer_capacity_;
- jpeg_mem_dest(&cinfo, &compression_buffer, &compression_buffer_size);
- jpeg_start_compress(&cinfo, true);
-
- while (cinfo.next_scanline < cinfo.image_height) {
- auto row = static_cast<JSAMPROW>(const_cast<std::uint8_t*>(
- &frame[(y * screen_width * BytesPerPixel()) +
- (cinfo.next_scanline * BytesPerPixel() * screen_width) +
- (x * BytesPerPixel())]));
- jpeg_write_scanlines(&cinfo, &row, 1);
- }
- jpeg_finish_compress(&cinfo);
- jpeg_destroy_compress(&cinfo);
-
- UpdateBuffer(compression_buffer, compression_buffer_size);
- return {compression_buffer, compression_buffer + compression_buffer_size};
-}
-
-void JpegCompressor::UpdateBuffer(std::uint8_t* compression_buffer,
- unsigned long compression_buffer_size) {
- if (buffer_capacity_ < compression_buffer_size) {
- ALOG_ASSERT(buffer_ != compression_buffer);
- buffer_capacity_ = compression_buffer_size;
- buffer_.reset(compression_buffer);
- } else {
- ALOG_ASSERT(buffer_ == compression_buffer);
- }
-}
diff --git a/guest/frontend/vnc_server/jpeg_compressor.h b/guest/frontend/vnc_server/jpeg_compressor.h
deleted file mode 100644
index d9c40ee..0000000
--- a/guest/frontend/vnc_server/jpeg_compressor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#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 "vnc_utils.h"
-
-#include <memory>
-#include <cstdlib>
-#include <cstdint>
-
-namespace cvd {
-namespace vnc {
-
-// libjpeg-turbo with jpeg_mem_dest (using memory as a destination) is funky.
-// If you give it a buffer that is big enough it will use it.
-// If you give it a buffer that is too small, it will allocate a new buffer
-// but will NOT free the buffer you gave it.
-// This class keeps track of the capacity of the working buffer, and frees the
-// old buffer if libjpeg-turbo silently discards it.
-class JpegCompressor {
- public:
- Message Compress(const Message& frame, int jpeg_quality, std::uint16_t x,
- std::uint16_t y, std::uint16_t width, std::uint16_t height,
- int screen_width);
-
- private:
- void UpdateBuffer(std::uint8_t* compression_buffer,
- unsigned long compression_buffer_size);
- struct Freer {
- void operator()(void* p) const {
- std::free(p);
- }
- };
-
- std::unique_ptr<std::uint8_t, Freer> buffer_;
- unsigned long buffer_capacity_{};
-};
-
-} // namespace vnc
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/keysyms.h b/guest/frontend/vnc_server/keysyms.h
deleted file mode 100644
index 8da0117..0000000
--- a/guest/frontend/vnc_server/keysyms.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#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.
- */
-
-namespace cvd {
-namespace xk {
-
-constexpr uint32_t BackSpace = 0xff08,
- Tab = 0xff09,
- Return = 0xff0d,
- Enter = Return,
- Escape = 0xff1b,
- MultiKey = 0xff20,
- Insert = 0xff63,
- Delete = 0xffff,
- Pause = 0xff13,
- Home = 0xff50,
- End = 0xff57,
- PageUp = 0xff55,
- PageDown = 0xff56,
- Left = 0xff51,
- Up = 0xff52,
- Right = 0xff53,
- Down = 0xff54,
- F1 = 0xffbe,
- F2 = 0xffbf,
- F3 = 0xffc0,
- F4 = 0xffc1,
- F5 = 0xffc2,
- F6 = 0xffc3,
- F7 = 0xffc4,
- F8 = 0xffc5,
- F9 = 0xffc6,
- F10 = 0xffc7,
- F11 = 0xffc8,
- F12 = 0xffc9,
- F13 = 0xffca,
- F14 = 0xffcb,
- F15 = 0xffcc,
- F16 = 0xffcd,
- F17 = 0xffce,
- F18 = 0xffcf,
- F19 = 0xffd0,
- F20 = 0xffd1,
- F21 = 0xffd2,
- F22 = 0xffd3,
- F23 = 0xffd4,
- F24 = 0xffd5,
- ShiftLeft = 0xffe1,
- ShiftRight = 0xffe2,
- ControlLeft = 0xffe3,
- ControlRight = 0xffe4,
- MetaLeft = 0xffe7,
- MetaRight = 0xffe8,
- AltLeft = 0xffe9,
- AltRight = 0xffea,
- CapsLock = 0xffe5,
- NumLock = 0xff7f,
- ScrollLock = 0xff14,
- Keypad0 = 0xffb0,
- Keypad1 = 0xffb1,
- Keypad2 = 0xffb2,
- Keypad3 = 0xffb3,
- Keypad4 = 0xffb4,
- Keypad5 = 0xffb5,
- Keypad6 = 0xffb6,
- Keypad7 = 0xffb7,
- Keypad8 = 0xffb8,
- Keypad9 = 0xffb9,
- KeypadMultiply = 0xffaa,
- KeypadSubtract = 0xffad,
- KeypadAdd = 0xffab,
- KeypadDecimal = 0xffae,
- KeypadEnter = 0xff8d,
- KeypadDivide = 0xffaf,
- KeypadEqual = 0xffbd,
- PlusMinus = 0xb1,
- SysReq = 0xff15,
- LineFeed = 0xff0a,
- KeypadSeparator = 0xffac,
- Yen = 0xa5,
- Cancel = 0xff69,
- Undo = 0xff65,
- Redo = 0xff66,
- Find = 0xff68,
- Print = 0xff61,
- VolumeDown = 0x1008ff11,
- Mute = 0x1008ff12,
- VolumeUp = 0x1008ff13,
- Menu = 0xff67,
- VNCMenu = 0xffed; // VNC seems to translate MENU to this
-
-} // namespace xk
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/main.cpp b/guest/frontend/vnc_server/main.cpp
deleted file mode 100644
index f03fdcb..0000000
--- a/guest/frontend/vnc_server/main.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 "vnc_server.h"
-
-#include <signal.h>
-#include <algorithm>
-#include <string>
-
-namespace {
-constexpr int kVncServerPort = 6444;
-
-// TODO(haining) use gflags when available
-bool HasAggressiveFlag(int argc, char* argv[]) {
- const std::string kAggressive = "--aggressive";
- auto end = argv + argc;
- return std::find(argv, end, kAggressive) != end;
-}
-} // namespace
-
-int main(int argc, char* argv[]) {
- struct sigaction new_action, old_action;
- memset(&new_action, 0, sizeof(new_action));
- new_action.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &new_action, &old_action);
- cvd::vnc::VncServer vnc_server(kVncServerPort, HasAggressiveFlag(argc, argv));
- vnc_server.MainLoop();
-}
diff --git a/guest/frontend/vnc_server/simulated_hw_composer.cpp b/guest/frontend/vnc_server/simulated_hw_composer.cpp
deleted file mode 100644
index f0e43bd..0000000
--- a/guest/frontend/vnc_server/simulated_hw_composer.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 "simulated_hw_composer.h"
-
-#include "common/vsoc/lib/framebuffer_region_view.h"
-
-using cvd::vnc::SimulatedHWComposer;
-using vsoc::framebuffer::FrameBufferRegionView;
-using vsoc::framebuffer::FBBroadcastRegionView;
-
-SimulatedHWComposer::SimulatedHWComposer(BlackBoard* bb)
- :
-#ifdef FUZZ_TEST_VNC
- engine_{std::random_device{}()},
-#endif
- bb_{bb},
- stripes_(kMaxQueueElements, &SimulatedHWComposer::EraseHalfOfElements) {
- stripe_maker_ = std::thread(&SimulatedHWComposer::MakeStripes, this);
-}
-
-SimulatedHWComposer::~SimulatedHWComposer() {
- close();
- stripe_maker_.join();
-}
-
-cvd::vnc::Stripe SimulatedHWComposer::GetNewStripe() {
- auto s = stripes_.Pop();
-#ifdef FUZZ_TEST_VNC
- if (random_(engine_)) {
- usleep(7000);
- stripes_.Push(std::move(s));
- s = stripes_.Pop();
- }
-#endif
- return s;
-}
-
-bool SimulatedHWComposer::closed() {
- std::lock_guard<std::mutex> guard(m_);
- return closed_;
-}
-
-void SimulatedHWComposer::close() {
- std::lock_guard<std::mutex> guard(m_);
- closed_ = true;
-}
-
-// Assuming the number of stripes is less than half the size of the queue
-// this will be safe as the newest stripes won't be lost. In the real
-// hwcomposer, where stripes are coming in a different order, the full
-// queue case would probably need a different approach to be safe.
-void SimulatedHWComposer::EraseHalfOfElements(
- ThreadSafeQueue<Stripe>::QueueImpl* q) {
- q->erase(q->begin(), std::next(q->begin(), kMaxQueueElements / 2));
-}
-
-void SimulatedHWComposer::MakeStripes() {
- std::uint32_t previous_seq_num{};
- auto screen_height = ActualScreenHeight();
- Message raw_screen;
- std::uint64_t stripe_seq_num = 1;
- while (!closed()) {
- bb_->WaitForAtLeastOneClientConnection();
- uint32_t offset =
- FBBroadcastRegionView::GetInstance()->WaitForNewFrameSince(
- &previous_seq_num);
- const char* frame_start = static_cast<char*>(
- FrameBufferRegionView::GetInstance()->GetBufferFromOffset(offset));
- raw_screen.assign(frame_start, frame_start + ScreenSizeInBytes());
-
- for (int i = 0; i < kNumStripes; ++i) {
- ++stripe_seq_num;
- std::uint16_t y = (screen_height / kNumStripes) * i;
-
- // Last frames on the right and/or bottom handle extra pixels
- // when a screen dimension is not evenly divisible by Frame::kNumSlots.
- std::uint16_t height =
- screen_height / kNumStripes +
- (i + 1 == kNumStripes ? screen_height % kNumStripes : 0);
- const auto* raw_start =
- &raw_screen[y * ActualScreenWidth() * BytesPerPixel()];
- const auto* raw_end =
- raw_start + (height * ActualScreenWidth() * BytesPerPixel());
- // creating a named object and setting individual data members in order
- // to make klp happy
- // TODO (haining) construct this inside the call when not compiling
- // on klp
- Stripe s{};
- s.index = i;
- s.frame_id = previous_seq_num;
- s.x = 0;
- s.y = y;
- s.width = ActualScreenWidth();
- s.height = height;
- s.raw_data.assign(raw_start, raw_end);
- s.seq_number = StripeSeqNumber{stripe_seq_num};
- s.orientation = ScreenOrientation::Portrait;
- stripes_.Push(std::move(s));
- }
- }
-}
-
-int SimulatedHWComposer::NumberOfStripes() {
- return kNumStripes;
-}
diff --git a/guest/frontend/vnc_server/simulated_hw_composer.h b/guest/frontend/vnc_server/simulated_hw_composer.h
deleted file mode 100644
index 79eeafd..0000000
--- a/guest/frontend/vnc_server/simulated_hw_composer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#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 <mutex>
-#include <thread>
-
-#include <condition_variable>
-#ifdef FUZZ_TEST_VNC
-#include <random>
-#endif
-
-#include "common/libs/thread_safe_queue/thread_safe_queue.h"
-#include "common/vsoc/lib/fb_bcast_region_view.h"
-
-#include "blackboard.h"
-
-namespace cvd {
-namespace vnc {
-class SimulatedHWComposer {
- public:
- SimulatedHWComposer(BlackBoard* bb);
- SimulatedHWComposer(const SimulatedHWComposer&) = delete;
- SimulatedHWComposer& operator=(const SimulatedHWComposer&) = delete;
- ~SimulatedHWComposer();
-
- Stripe GetNewStripe();
-
- // NOTE not constexpr on purpose
- static int NumberOfStripes();
-
- private:
- bool closed();
- void close();
- static void EraseHalfOfElements(ThreadSafeQueue<Stripe>::QueueImpl* q);
- void MakeStripes();
-
-#ifdef FUZZ_TEST_VNC
- std::default_random_engine engine_;
- std::uniform_int_distribution<int> random_ =
- std::uniform_int_distribution<int>{0, 2};
-#endif
- static constexpr int kNumStripes = 8;
- constexpr static std::size_t kMaxQueueElements = 64;
- bool closed_ GUARDED_BY(m_){};
- std::mutex m_;
- BlackBoard* bb_{};
- ThreadSafeQueue<Stripe> stripes_;
- std::thread stripe_maker_;
-};
-} // namespace vnc
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/virtual_inputs.cpp b/guest/frontend/vnc_server/virtual_inputs.cpp
deleted file mode 100644
index 822f47c..0000000
--- a/guest/frontend/vnc_server/virtual_inputs.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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 "virtual_inputs.h"
-
-#include <linux/input.h>
-#include <linux/uinput.h>
-
-#include <mutex>
-
-#include "log/log.h"
-
-#include "keysyms.h"
-
-using cvd::vnc::VirtualInputs;
-using vsoc::input_events::InputEventsRegionView;
-
-namespace {
-void AddKeyMappings(std::map<uint32_t, uint32_t>* key_mapping) {
- (*key_mapping)[cvd::xk::AltLeft] = KEY_LEFTALT;
- (*key_mapping)[cvd::xk::ControlLeft] = KEY_LEFTCTRL;
- (*key_mapping)[cvd::xk::ShiftLeft] = KEY_LEFTSHIFT;
- (*key_mapping)[cvd::xk::AltRight] = KEY_RIGHTALT;
- (*key_mapping)[cvd::xk::ControlRight] = KEY_RIGHTCTRL;
- (*key_mapping)[cvd::xk::ShiftRight] = KEY_RIGHTSHIFT;
- (*key_mapping)[cvd::xk::MetaLeft] = KEY_LEFTMETA;
- (*key_mapping)[cvd::xk::MetaRight] = KEY_RIGHTMETA;
- (*key_mapping)[cvd::xk::MultiKey] = KEY_COMPOSE;
-
- (*key_mapping)[cvd::xk::CapsLock] = KEY_CAPSLOCK;
- (*key_mapping)[cvd::xk::NumLock] = KEY_NUMLOCK;
- (*key_mapping)[cvd::xk::ScrollLock] = KEY_SCROLLLOCK;
-
- (*key_mapping)[cvd::xk::BackSpace] = KEY_BACKSPACE;
- (*key_mapping)[cvd::xk::Tab] = KEY_TAB;
- (*key_mapping)[cvd::xk::Return] = KEY_ENTER;
- (*key_mapping)[cvd::xk::Escape] = KEY_ESC;
-
- (*key_mapping)[' '] = KEY_SPACE;
- (*key_mapping)['!'] = KEY_1;
- (*key_mapping)['"'] = KEY_APOSTROPHE;
- (*key_mapping)['#'] = KEY_3;
- (*key_mapping)['$'] = KEY_4;
- (*key_mapping)['%'] = KEY_5;
- (*key_mapping)['^'] = KEY_6;
- (*key_mapping)['&'] = KEY_7;
- (*key_mapping)['\''] = KEY_APOSTROPHE;
- (*key_mapping)['('] = KEY_9;
- (*key_mapping)[')'] = KEY_0;
- (*key_mapping)['*'] = KEY_8;
- (*key_mapping)['+'] = KEY_EQUAL;
- (*key_mapping)[','] = KEY_COMMA;
- (*key_mapping)['-'] = KEY_MINUS;
- (*key_mapping)['.'] = KEY_DOT;
- (*key_mapping)['/'] = KEY_SLASH;
- (*key_mapping)['0'] = KEY_0;
- (*key_mapping)['1'] = KEY_1;
- (*key_mapping)['2'] = KEY_2;
- (*key_mapping)['3'] = KEY_3;
- (*key_mapping)['4'] = KEY_4;
- (*key_mapping)['5'] = KEY_5;
- (*key_mapping)['6'] = KEY_6;
- (*key_mapping)['7'] = KEY_7;
- (*key_mapping)['8'] = KEY_8;
- (*key_mapping)['9'] = KEY_9;
- (*key_mapping)[':'] = KEY_SEMICOLON;
- (*key_mapping)[';'] = KEY_SEMICOLON;
- (*key_mapping)['<'] = KEY_COMMA;
- (*key_mapping)['='] = KEY_EQUAL;
- (*key_mapping)['>'] = KEY_DOT;
- (*key_mapping)['?'] = KEY_SLASH;
- (*key_mapping)['@'] = KEY_2;
- (*key_mapping)['A'] = KEY_A;
- (*key_mapping)['B'] = KEY_B;
- (*key_mapping)['C'] = KEY_C;
- (*key_mapping)['D'] = KEY_D;
- (*key_mapping)['E'] = KEY_E;
- (*key_mapping)['F'] = KEY_F;
- (*key_mapping)['G'] = KEY_G;
- (*key_mapping)['H'] = KEY_H;
- (*key_mapping)['I'] = KEY_I;
- (*key_mapping)['J'] = KEY_J;
- (*key_mapping)['K'] = KEY_K;
- (*key_mapping)['L'] = KEY_L;
- (*key_mapping)['M'] = KEY_M;
- (*key_mapping)['N'] = KEY_N;
- (*key_mapping)['O'] = KEY_O;
- (*key_mapping)['P'] = KEY_P;
- (*key_mapping)['Q'] = KEY_Q;
- (*key_mapping)['R'] = KEY_R;
- (*key_mapping)['S'] = KEY_S;
- (*key_mapping)['T'] = KEY_T;
- (*key_mapping)['U'] = KEY_U;
- (*key_mapping)['V'] = KEY_V;
- (*key_mapping)['W'] = KEY_W;
- (*key_mapping)['X'] = KEY_X;
- (*key_mapping)['Y'] = KEY_Y;
- (*key_mapping)['Z'] = KEY_Z;
- (*key_mapping)['['] = KEY_LEFTBRACE;
- (*key_mapping)['\\'] = KEY_BACKSLASH;
- (*key_mapping)[']'] = KEY_RIGHTBRACE;
- (*key_mapping)['-'] = KEY_MINUS;
- (*key_mapping)['_'] = KEY_MINUS;
- (*key_mapping)['`'] = KEY_GRAVE;
- (*key_mapping)['a'] = KEY_A;
- (*key_mapping)['b'] = KEY_B;
- (*key_mapping)['c'] = KEY_C;
- (*key_mapping)['d'] = KEY_D;
- (*key_mapping)['e'] = KEY_E;
- (*key_mapping)['f'] = KEY_F;
- (*key_mapping)['g'] = KEY_G;
- (*key_mapping)['h'] = KEY_H;
- (*key_mapping)['i'] = KEY_I;
- (*key_mapping)['j'] = KEY_J;
- (*key_mapping)['k'] = KEY_K;
- (*key_mapping)['l'] = KEY_L;
- (*key_mapping)['m'] = KEY_M;
- (*key_mapping)['n'] = KEY_N;
- (*key_mapping)['o'] = KEY_O;
- (*key_mapping)['p'] = KEY_P;
- (*key_mapping)['q'] = KEY_Q;
- (*key_mapping)['r'] = KEY_R;
- (*key_mapping)['s'] = KEY_S;
- (*key_mapping)['t'] = KEY_T;
- (*key_mapping)['u'] = KEY_U;
- (*key_mapping)['v'] = KEY_V;
- (*key_mapping)['w'] = KEY_W;
- (*key_mapping)['x'] = KEY_X;
- (*key_mapping)['y'] = KEY_Y;
- (*key_mapping)['z'] = KEY_Z;
- (*key_mapping)['{'] = KEY_LEFTBRACE;
- (*key_mapping)['\\'] = KEY_BACKSLASH;
- (*key_mapping)['|'] = KEY_BACKSLASH;
- (*key_mapping)['}'] = KEY_RIGHTBRACE;
- (*key_mapping)['~'] = KEY_GRAVE;
-
- (*key_mapping)[cvd::xk::F1] = KEY_F1;
- (*key_mapping)[cvd::xk::F2] = KEY_F2;
- (*key_mapping)[cvd::xk::F3] = KEY_F3;
- (*key_mapping)[cvd::xk::F4] = KEY_F4;
- (*key_mapping)[cvd::xk::F5] = KEY_F5;
- (*key_mapping)[cvd::xk::F6] = KEY_F6;
- (*key_mapping)[cvd::xk::F7] = KEY_F7;
- (*key_mapping)[cvd::xk::F8] = KEY_F8;
- (*key_mapping)[cvd::xk::F9] = KEY_F9;
- (*key_mapping)[cvd::xk::F10] = KEY_F10;
- (*key_mapping)[cvd::xk::F11] = KEY_F11;
- (*key_mapping)[cvd::xk::F12] = KEY_F12;
- (*key_mapping)[cvd::xk::F13] = KEY_F13;
- (*key_mapping)[cvd::xk::F14] = KEY_F14;
- (*key_mapping)[cvd::xk::F15] = KEY_F15;
- (*key_mapping)[cvd::xk::F16] = KEY_F16;
- (*key_mapping)[cvd::xk::F17] = KEY_F17;
- (*key_mapping)[cvd::xk::F18] = KEY_F18;
- (*key_mapping)[cvd::xk::F19] = KEY_F19;
- (*key_mapping)[cvd::xk::F20] = KEY_F20;
- (*key_mapping)[cvd::xk::F21] = KEY_F21;
- (*key_mapping)[cvd::xk::F22] = KEY_F22;
- (*key_mapping)[cvd::xk::F23] = KEY_F23;
- (*key_mapping)[cvd::xk::F24] = KEY_F24;
-
- (*key_mapping)[cvd::xk::Keypad0] = KEY_KP0;
- (*key_mapping)[cvd::xk::Keypad1] = KEY_KP1;
- (*key_mapping)[cvd::xk::Keypad2] = KEY_KP2;
- (*key_mapping)[cvd::xk::Keypad3] = KEY_KP3;
- (*key_mapping)[cvd::xk::Keypad4] = KEY_KP4;
- (*key_mapping)[cvd::xk::Keypad5] = KEY_KP5;
- (*key_mapping)[cvd::xk::Keypad6] = KEY_KP6;
- (*key_mapping)[cvd::xk::Keypad7] = KEY_KP7;
- (*key_mapping)[cvd::xk::Keypad8] = KEY_KP8;
- (*key_mapping)[cvd::xk::Keypad9] = KEY_KP9;
- (*key_mapping)[cvd::xk::KeypadMultiply] = KEY_KPASTERISK;
- (*key_mapping)[cvd::xk::KeypadSubtract] = KEY_KPMINUS;
- (*key_mapping)[cvd::xk::KeypadAdd] = KEY_KPPLUS;
- (*key_mapping)[cvd::xk::KeypadDecimal] = KEY_KPDOT;
- (*key_mapping)[cvd::xk::KeypadEnter] = KEY_KPENTER;
- (*key_mapping)[cvd::xk::KeypadDivide] = KEY_KPSLASH;
- (*key_mapping)[cvd::xk::KeypadEqual] = KEY_KPEQUAL;
- (*key_mapping)[cvd::xk::PlusMinus] = KEY_KPPLUSMINUS;
-
- (*key_mapping)[cvd::xk::SysReq] = KEY_SYSRQ;
- (*key_mapping)[cvd::xk::LineFeed] = KEY_LINEFEED;
- (*key_mapping)[cvd::xk::Home] = KEY_HOME;
- (*key_mapping)[cvd::xk::Up] = KEY_UP;
- (*key_mapping)[cvd::xk::PageUp] = KEY_PAGEUP;
- (*key_mapping)[cvd::xk::Left] = KEY_LEFT;
- (*key_mapping)[cvd::xk::Right] = KEY_RIGHT;
- (*key_mapping)[cvd::xk::End] = KEY_END;
- (*key_mapping)[cvd::xk::Down] = KEY_DOWN;
- (*key_mapping)[cvd::xk::PageDown] = KEY_PAGEDOWN;
- (*key_mapping)[cvd::xk::Insert] = KEY_INSERT;
- (*key_mapping)[cvd::xk::Delete] = KEY_DELETE;
- (*key_mapping)[cvd::xk::Pause] = KEY_PAUSE;
- (*key_mapping)[cvd::xk::KeypadSeparator] = KEY_KPCOMMA;
- (*key_mapping)[cvd::xk::Yen] = KEY_YEN;
- (*key_mapping)[cvd::xk::Cancel] = KEY_STOP;
- (*key_mapping)[cvd::xk::Redo] = KEY_AGAIN;
- (*key_mapping)[cvd::xk::Undo] = KEY_UNDO;
- (*key_mapping)[cvd::xk::Find] = KEY_FIND;
- (*key_mapping)[cvd::xk::Print] = KEY_PRINT;
- (*key_mapping)[cvd::xk::VolumeDown] = KEY_VOLUMEDOWN;
- (*key_mapping)[cvd::xk::Mute] = KEY_MUTE;
- (*key_mapping)[cvd::xk::VolumeUp] = KEY_VOLUMEUP;
- (*key_mapping)[cvd::xk::Menu] = KEY_MENU;
- (*key_mapping)[cvd::xk::VNCMenu] = KEY_MENU;
-}
-} // namespace
-
-VirtualInputs::VirtualInputs() {
- input_events_region_view_ =
- vsoc::input_events::InputEventsRegionView::GetInstance();
- LOG_FATAL_IF(!input_events_region_view_,
- "Failed to open Input events region view");
- AddKeyMappings(&keymapping_);
-}
-
-void VirtualInputs::GenerateKeyPressEvent(int key_code, bool down) {
- if (keymapping_.count(key_code)) {
- input_events_region_view_->HandleKeyboardEvent(down, keymapping_[key_code]);
- } else {
- ALOGI("Unknown keycode %d", key_code);
- }
-}
-
-void VirtualInputs::PressPowerButton(bool down) {
- input_events_region_view_->HandlePowerButtonEvent(down);
-}
-
-void VirtualInputs::HandlePointerEvent(bool touch_down, int x, int y) {
- input_events_region_view_->HandleSingleTouchEvent(touch_down, x, y);
-}
diff --git a/guest/frontend/vnc_server/virtual_inputs.h b/guest/frontend/vnc_server/virtual_inputs.h
deleted file mode 100644
index 3b129af..0000000
--- a/guest/frontend/vnc_server/virtual_inputs.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#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 "vnc_utils.h"
-
-#include <map>
-#include <mutex>
-
-#include "common/vsoc/lib/input_events_region_view.h"
-
-namespace cvd {
-namespace vnc {
-
-class VirtualInputs {
- public:
- VirtualInputs();
-
- void GenerateKeyPressEvent(int code, bool down);
- void PressPowerButton(bool down);
- void HandlePointerEvent(bool touch_down, int x, int y);
-
- private:
- std::shared_ptr<vsoc::input_events::InputEventsRegionView>
- input_events_region_view_;
- std::map<uint32_t, uint32_t> keymapping_;
-};
-
-} // namespace vnc
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/vnc_client_connection.cpp b/guest/frontend/vnc_server/vnc_client_connection.cpp
deleted file mode 100644
index b3f272e..0000000
--- a/guest/frontend/vnc_server/vnc_client_connection.cpp
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * 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 "vnc_client_connection.h"
-#include "keysyms.h"
-#include "vnc_utils.h"
-
-#include "common/libs/tcp_socket/tcp_socket.h"
-
-#include <netinet/in.h>
-#include <sys/time.h>
-
-#include <algorithm>
-#include <cmath>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <thread>
-#include <utility>
-#include <vector>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG ""
-#include <cutils/log.h>
-#include <cutils/sockets.h>
-
-using cvd::Message;
-using cvd::vnc::Stripe;
-using cvd::vnc::StripePtrVec;
-using cvd::vnc::VncClientConnection;
-using vsoc::framebuffer::FBBroadcastRegionView;
-
-namespace {
-class BigEndianChecker {
- public:
- BigEndianChecker() {
- uint32_t u = 1;
- is_big_endian_ = *reinterpret_cast<const char*>(&u) == 0;
- }
- bool operator()() const { return is_big_endian_; }
-
- private:
- bool is_big_endian_{};
-};
-
-const BigEndianChecker ImBigEndian;
-
-constexpr int32_t kDesktopSizeEncoding = -223;
-constexpr int32_t kTightEncoding = 7;
-
-// These are the lengths not counting the first byte. The first byte
-// indicates the message type.
-constexpr size_t kSetPixelFormatLength = 19;
-constexpr size_t kFramebufferUpdateRequestLength = 9;
-constexpr size_t kSetEncodingsLength = 3; // more bytes follow
-constexpr size_t kKeyEventLength = 7;
-constexpr size_t kPointerEventLength = 5;
-constexpr size_t kClientCutTextLength = 7; // more bytes follow
-
-void AppendInNetworkByteOrder(Message* msg, const std::uint8_t b) {
- msg->push_back(b);
-}
-
-void AppendInNetworkByteOrder(Message* msg, const std::uint16_t s) {
- const std::uint16_t n = htons(s);
- auto p = reinterpret_cast<const std::uint8_t*>(&n);
- msg->insert(msg->end(), p, p + sizeof n);
-}
-
-void AppendInNetworkByteOrder(Message* msg, const std::uint32_t w) {
- const std::uint32_t n = htonl(w);
- auto p = reinterpret_cast<const std::uint8_t*>(&n);
- msg->insert(msg->end(), p, p + sizeof n);
-}
-
-void AppendInNetworkByteOrder(Message* msg, const int32_t w) {
- std::uint32_t u{};
- std::memcpy(&u, &w, sizeof u);
- AppendInNetworkByteOrder(msg, u);
-}
-
-void AppendInNetworkByteOrder(Message* msg, const std::string& str) {
- msg->insert(msg->end(), str.begin(), str.end());
-}
-
-void AppendToMessage(Message*) {}
-
-template <typename T, typename... Ts>
-void AppendToMessage(Message* msg, T v, Ts... vals) {
- AppendInNetworkByteOrder(msg, v);
- AppendToMessage(msg, vals...);
-}
-
-template <typename... Ts>
-Message CreateMessage(Ts... vals) {
- Message m;
- AppendToMessage(&m, vals...);
- return m;
-}
-
-std::string HostName() { return "Cuttlefish"; }
-
-std::uint16_t uint16_tAt(const void* p) {
- std::uint16_t u{};
- std::memcpy(&u, p, sizeof u);
- return ntohs(u);
-}
-
-std::uint32_t uint32_tAt(const void* p) {
- std::uint32_t u{};
- std::memcpy(&u, p, sizeof u);
- return ntohl(u);
-}
-
-std::int32_t int32_tAt(const void* p) {
- std::uint32_t u{};
- std::memcpy(&u, p, sizeof u);
- u = ntohl(u);
- std::int32_t s{};
- std::memcpy(&s, &u, sizeof s);
- return s;
-}
-
-std::uint32_t RedVal(std::uint32_t pixel) {
- return (pixel >> FBBroadcastRegionView::kRedShift) &
- ((0x1 << FBBroadcastRegionView::kRedBits) - 1);
-}
-
-std::uint32_t BlueVal(std::uint32_t pixel) {
- return (pixel >> FBBroadcastRegionView::kBlueShift) &
- ((0x1 << FBBroadcastRegionView::kBlueBits) - 1);
-}
-
-std::uint32_t GreenVal(std::uint32_t pixel) {
- return (pixel >> FBBroadcastRegionView::kGreenShift) &
- ((0x1 << FBBroadcastRegionView::kGreenBits) - 1);
-}
-} // namespace
-namespace cvd {
-namespace vnc {
-bool operator==(const VncClientConnection::FrameBufferUpdateRequest& lhs,
- const VncClientConnection::FrameBufferUpdateRequest& rhs) {
- return lhs.x_pos == rhs.x_pos && lhs.y_pos == rhs.y_pos &&
- lhs.width == rhs.width && lhs.height == rhs.height;
-}
-
-bool operator!=(const VncClientConnection::FrameBufferUpdateRequest& lhs,
- const VncClientConnection::FrameBufferUpdateRequest& rhs) {
- return !(lhs == rhs);
-}
-} // namespace vnc
-} // namespace cvd
-
-VncClientConnection::VncClientConnection(ClientSocket client,
- VirtualInputs* virtual_inputs,
- BlackBoard* bb, bool aggressive)
- : client_{std::move(client)}, virtual_inputs_{virtual_inputs}, bb_{bb} {
- frame_buffer_request_handler_tid_ = std::thread(
- &VncClientConnection::FrameBufferUpdateRequestHandler, this, aggressive);
-}
-
-VncClientConnection::~VncClientConnection() {
- {
- std::lock_guard<std::mutex> guard(m_);
- closed_ = true;
- }
- bb_->StopWaiting(this);
- frame_buffer_request_handler_tid_.join();
-}
-
-void VncClientConnection::StartSession() {
- SetupProtocol();
- if (client_.closed()) {
- return;
- }
- SetupSecurityType();
- if (client_.closed()) {
- return;
- }
- GetClientInit();
- if (client_.closed()) {
- return;
- }
- SendServerInit();
- if (client_.closed()) {
- return;
- }
- NormalSession();
- ALOGI("vnc session terminated");
-}
-
-bool VncClientConnection::closed() {
- std::lock_guard<std::mutex> guard(m_);
- return closed_;
-}
-
-void VncClientConnection::SetupProtocol() {
- static constexpr char kRFBVersion[] = "RFB 003.008\n";
- static constexpr auto kVersionLen = (sizeof kRFBVersion) - 1;
- client_.Send(reinterpret_cast<const std::uint8_t*>(kRFBVersion), kVersionLen);
- auto client_protocol = client_.Recv(kVersionLen);
- if (std::memcmp(&client_protocol[0], kRFBVersion,
- std::min(kVersionLen, client_protocol.size())) != 0) {
- client_protocol.push_back('\0');
- ALOGE("vnc client wants a different protocol: %s",
- reinterpret_cast<const char*>(&client_protocol[0]));
- }
-}
-
-void VncClientConnection::SetupSecurityType() {
- static constexpr std::uint8_t kNoneSecurity = 0x1;
- // The first '0x1' indicates the number of items that follow
- static constexpr std::uint8_t kOnlyNoneSecurity[] = {0x01, kNoneSecurity};
- client_.Send(kOnlyNoneSecurity);
- auto client_security = client_.Recv(1);
- if (client_.closed()) {
- return;
- }
- if (client_security.front() != kNoneSecurity) {
- ALOGE("vnc client is asking for security type %d",
- static_cast<int>(client_security.front()));
- }
- static constexpr std::uint8_t kZero[4] = {};
- client_.Send(kZero);
-}
-
-void VncClientConnection::GetClientInit() {
- auto client_shared = client_.Recv(1);
-}
-
-void VncClientConnection::SendServerInit() {
- const std::string server_name = HostName();
- std::lock_guard<std::mutex> guard(m_);
- auto server_init = CreateMessage(
- static_cast<std::uint16_t>(ScreenWidth()),
- static_cast<std::uint16_t>(ScreenHeight()), pixel_format_.bits_per_pixel,
- pixel_format_.depth, pixel_format_.big_endian, pixel_format_.true_color,
- pixel_format_.red_max, pixel_format_.green_max, pixel_format_.blue_max,
- pixel_format_.red_shift, pixel_format_.green_shift,
- pixel_format_.blue_shift, std::uint16_t{}, // padding
- std::uint8_t{}, // padding
- static_cast<std::uint32_t>(server_name.size()), server_name);
- client_.Send(server_init);
-}
-
-Message VncClientConnection::MakeFrameBufferUpdateHeader(
- std::uint16_t num_stripes) {
- return CreateMessage(std::uint8_t{0}, // message-type
- std::uint8_t{}, // padding
- std::uint16_t{num_stripes});
-}
-
-void VncClientConnection::AppendRawStripeHeader(Message* frame_buffer_update,
- const Stripe& stripe) {
- static constexpr int32_t kRawEncoding = 0;
- AppendToMessage(frame_buffer_update, std::uint16_t{stripe.x},
- std::uint16_t{stripe.y}, std::uint16_t{stripe.width},
- std::uint16_t{stripe.height}, kRawEncoding);
-}
-
-void VncClientConnection::AppendJpegSize(Message* frame_buffer_update,
- size_t jpeg_size) {
- constexpr size_t kJpegSizeOneByteMax = 127;
- constexpr size_t kJpegSizeTwoByteMax = 16383;
- constexpr size_t kJpegSizeThreeByteMax = 4194303;
-
- if (jpeg_size <= kJpegSizeOneByteMax) {
- AppendToMessage(frame_buffer_update, static_cast<std::uint8_t>(jpeg_size));
- } else if (jpeg_size <= kJpegSizeTwoByteMax) {
- auto sz = static_cast<std::uint32_t>(jpeg_size);
- AppendToMessage(frame_buffer_update,
- static_cast<std::uint8_t>((sz & 0x7F) | 0x80),
- static_cast<std::uint8_t>((sz >> 7) & 0xFF));
- } else {
- if (jpeg_size > kJpegSizeThreeByteMax) {
- LOG_FATAL("jpeg size is too big: %d must be under %zu", jpeg_size,
- kJpegSizeThreeByteMax);
- }
- const auto sz = static_cast<std::uint32_t>(jpeg_size);
- AppendToMessage(frame_buffer_update,
- static_cast<std::uint8_t>((sz & 0x7F) | 0x80),
- static_cast<std::uint8_t>(((sz >> 7) & 0x7F) | 0x80),
- static_cast<std::uint8_t>((sz >> 14) & 0xFF));
- }
-}
-
-void VncClientConnection::AppendRawStripe(Message* frame_buffer_update,
- const Stripe& stripe) const {
- using Pixel = FBBroadcastRegionView::Pixel;
- auto& fbu = *frame_buffer_update;
- AppendRawStripeHeader(&fbu, stripe);
- auto init_size = fbu.size();
- fbu.insert(fbu.end(), stripe.raw_data.begin(), stripe.raw_data.end());
- for (size_t i = init_size; i < fbu.size(); i += sizeof(Pixel)) {
- ALOG_ASSERT((i + sizeof(Pixel)) < fbu.size());
- Pixel raw_pixel{};
- std::memcpy(&raw_pixel, &fbu[i], sizeof raw_pixel);
- auto red = RedVal(raw_pixel);
- auto green = GreenVal(raw_pixel);
- auto blue = BlueVal(raw_pixel);
- Pixel pixel = Pixel{red} << pixel_format_.red_shift |
- Pixel{blue} << pixel_format_.blue_shift |
- Pixel{green} << pixel_format_.green_shift;
-
- if (bool(pixel_format_.big_endian) != ImBigEndian()) {
- // flip them bits (refactor into function)
- auto p = reinterpret_cast<char*>(&pixel);
- std::swap(p[0], p[3]);
- std::swap(p[1], p[2]);
- }
- ALOG_ASSERT(i + sizeof pixel <= fbu.size());
- std::memcpy(&fbu[i], &pixel, sizeof pixel);
- }
-}
-
-Message VncClientConnection::MakeRawFrameBufferUpdate(
- const StripePtrVec& stripes) const {
- auto fbu =
- MakeFrameBufferUpdateHeader(static_cast<std::uint16_t>(stripes.size()));
- for (auto& stripe : stripes) {
- AppendRawStripe(&fbu, *stripe);
- }
- return fbu;
-}
-
-void VncClientConnection::AppendJpegStripeHeader(Message* frame_buffer_update,
- const Stripe& stripe) {
- static constexpr std::uint8_t kJpegEncoding = 0x90;
- AppendToMessage(frame_buffer_update, stripe.x, stripe.y, stripe.width,
- stripe.height, kTightEncoding, kJpegEncoding);
- AppendJpegSize(frame_buffer_update, stripe.jpeg_data.size());
-}
-
-void VncClientConnection::AppendJpegStripe(Message* frame_buffer_update,
- const Stripe& stripe) {
- AppendJpegStripeHeader(frame_buffer_update, stripe);
- frame_buffer_update->insert(frame_buffer_update->end(),
- stripe.jpeg_data.begin(), stripe.jpeg_data.end());
-}
-
-Message VncClientConnection::MakeJpegFrameBufferUpdate(
- const StripePtrVec& stripes) {
- auto fbu =
- MakeFrameBufferUpdateHeader(static_cast<std::uint16_t>(stripes.size()));
- for (auto& stripe : stripes) {
- AppendJpegStripe(&fbu, *stripe);
- }
- return fbu;
-}
-
-Message VncClientConnection::MakeFrameBufferUpdate(
- const StripePtrVec& stripes) {
- return use_jpeg_compression_ ? MakeJpegFrameBufferUpdate(stripes)
- : MakeRawFrameBufferUpdate(stripes);
-}
-
-void VncClientConnection::FrameBufferUpdateRequestHandler(bool aggressive) {
- BlackBoard::Registerer reg(bb_, this);
-
- while (!closed()) {
- auto stripes = bb_->WaitForSenderWork(this);
- if (closed()) {
- break;
- }
- LOG_ALWAYS_FATAL_IF(stripes.empty(), "Got 0 stripes");
- {
- // lock here so a portrait frame can't be sent after a landscape
- // DesktopSize update, or vice versa.
- std::lock_guard<std::mutex> guard(m_);
- D("Sending update in %s mode",
- current_orientation_ == ScreenOrientation::Portrait ? "portrait"
- : "landscape");
- client_.Send(MakeFrameBufferUpdate(stripes));
- }
- if (aggressive) {
- bb_->FrameBufferUpdateRequestReceived(this);
- }
- }
-}
-
-void VncClientConnection::SendDesktopSizeUpdate() {
- static constexpr int32_t kDesktopSizeEncoding = -223;
- client_.Send(CreateMessage(std::uint8_t{0}, // message-type,
- std::uint8_t{}, // padding
- std::uint16_t{1}, // one pseudo rectangle
- std::uint16_t{0}, std::uint16_t{0},
- static_cast<std::uint16_t>(ScreenWidth()),
- static_cast<std::uint16_t>(ScreenHeight()),
- kDesktopSizeEncoding));
-}
-
-bool VncClientConnection::IsUrgent(
- const FrameBufferUpdateRequest& update_request) const {
- return !update_request.incremental ||
- update_request != previous_update_request_;
-}
-
-void VncClientConnection::HandleFramebufferUpdateRequest() {
- auto msg = client_.Recv(kFramebufferUpdateRequestLength);
- if (msg.size() != kFramebufferUpdateRequestLength) {
- return;
- }
- FrameBufferUpdateRequest fbur{msg[1] == 0, uint16_tAt(&msg[1]),
- uint16_tAt(&msg[3]), uint16_tAt(&msg[5]),
- uint16_tAt(&msg[7])};
- if (IsUrgent(fbur)) {
- bb_->SignalClientNeedsEntireScreen(this);
- }
- bb_->FrameBufferUpdateRequestReceived(this);
- previous_update_request_ = fbur;
-}
-
-void VncClientConnection::HandleSetEncodings() {
- auto msg = client_.Recv(kSetEncodingsLength);
- if (msg.size() != kSetEncodingsLength) {
- return;
- }
- auto count = uint16_tAt(&msg[1]);
- auto encodings = client_.Recv(count * sizeof(int32_t));
- if (encodings.size() % sizeof(int32_t) != 0) {
- return;
- }
- {
- std::lock_guard<std::mutex> guard(m_);
- use_jpeg_compression_ = false;
- }
- for (size_t i = 0; i < encodings.size(); i += sizeof(int32_t)) {
- auto enc = int32_tAt(&encodings[i]);
- D("client requesting encoding: %d\n", enc);
- if (enc == kTightEncoding) {
- // This is a deviation from the spec which says that if a jpeg quality
- // level is not specified, tight encoding won't use jpeg.
- std::lock_guard<std::mutex> guard(m_);
- use_jpeg_compression_ = true;
- }
- if (kJpegMinQualityEncoding <= enc && enc <= kJpegMaxQualityEncoding) {
- D("jpeg compression level: %d", enc);
- bb_->set_jpeg_quality_level(enc);
- }
- if (enc == kDesktopSizeEncoding) {
- supports_desktop_size_encoding_ = true;
- }
- }
-}
-
-void VncClientConnection::HandleSetPixelFormat() {
- std::lock_guard<std::mutex> guard(m_);
- auto msg = client_.Recv(kSetPixelFormatLength);
- if (msg.size() != kSetPixelFormatLength) {
- return;
- }
- pixel_format_.bits_per_pixel = msg[3];
- pixel_format_.depth = msg[4];
- pixel_format_.big_endian = msg[5];
- pixel_format_.true_color = msg[7];
- pixel_format_.red_max = uint16_tAt(&msg[8]);
- pixel_format_.green_max = uint16_tAt(&msg[10]);
- pixel_format_.blue_max = uint16_tAt(&msg[12]);
- pixel_format_.red_shift = msg[13];
- pixel_format_.green_shift = msg[14];
- pixel_format_.blue_shift = msg[15];
-}
-
-void VncClientConnection::HandlePointerEvent() {
- auto msg = client_.Recv(kPointerEventLength);
- if (msg.size() != kPointerEventLength) {
- return;
- }
- std::uint8_t button_mask = msg[0];
- auto x_pos = uint16_tAt(&msg[1]);
- auto y_pos = uint16_tAt(&msg[3]);
- {
- std::lock_guard<std::mutex> guard(m_);
- if (current_orientation_ == ScreenOrientation::Landscape) {
- std::tie(x_pos, y_pos) =
- std::make_pair(ActualScreenWidth() - y_pos, x_pos);
- }
- }
- virtual_inputs_->HandlePointerEvent(button_mask, x_pos, y_pos);
-}
-
-void VncClientConnection::UpdateAccelerometer(float /*x*/, float /*y*/,
- float /*z*/) {
- // TODO(jemoreira): Implement when vsoc sensor hal is updated
-}
-
-VncClientConnection::Coordinates VncClientConnection::CoordinatesForOrientation(
- ScreenOrientation orientation) const {
- // Compute the acceleration vector that we need to send to mimic
- // this change.
- constexpr float g = 9.81;
- constexpr float angle = 20.0;
- const float cos_angle = std::cos(angle / M_PI);
- const float sin_angle = std::sin(angle / M_PI);
- const float z = g * sin_angle;
- switch (orientation) {
- case ScreenOrientation::Portrait:
- return {0, g * cos_angle, z};
- case ScreenOrientation::Landscape:
- return {g * cos_angle, 0, z};
- }
-}
-
-int VncClientConnection::ScreenWidth() const {
- return current_orientation_ == ScreenOrientation::Portrait
- ? ActualScreenWidth()
- : ActualScreenHeight();
-}
-
-int VncClientConnection::ScreenHeight() const {
- return current_orientation_ == ScreenOrientation::Portrait
- ? ActualScreenHeight()
- : ActualScreenWidth();
-}
-
-void VncClientConnection::SetScreenOrientation(ScreenOrientation orientation) {
- std::lock_guard<std::mutex> guard(m_);
- auto coords = CoordinatesForOrientation(orientation);
- UpdateAccelerometer(coords.x, coords.y, coords.z);
- if (supports_desktop_size_encoding_) {
- auto previous_orientation = current_orientation_;
- current_orientation_ = orientation;
- if (current_orientation_ != previous_orientation &&
- supports_desktop_size_encoding_) {
- SendDesktopSizeUpdate();
- bb_->SetOrientation(this, current_orientation_);
- // TODO not sure if I should be sending a frame update along with this,
- // or just letting the next FBUR handle it. This seems to me like it's
- // sending one more frame buffer update than was requested, which is
- // maybe a violation of the spec?
- }
- }
-}
-
-bool VncClientConnection::RotateIfIsRotationCommand(std::uint32_t key) {
- // Due to different configurations on different platforms we're supporting
- // a set of options for rotating the screen. These are similar to what
- // the emulator supports and has supported.
- // ctrl+left and ctrl+right work on windows and linux
- // command+left and command+right work on Mac
- // ctrl+fn+F11 and ctrl+fn+F12 work when chromoting to ubuntu from a Mac
- if (!control_key_down_ && !meta_key_down_) {
- return false;
- }
- switch (key) {
- case cvd::xk::Right:
- case cvd::xk::F12:
- D("switching to portrait");
- SetScreenOrientation(ScreenOrientation::Portrait);
- break;
- case cvd::xk::Left:
- case cvd::xk::F11:
- D("switching to landscape");
- SetScreenOrientation(ScreenOrientation::Landscape);
- break;
- default:
- return false;
- }
- return true;
-}
-
-void VncClientConnection::HandleKeyEvent() {
- auto msg = client_.Recv(kKeyEventLength);
- if (msg.size() != kKeyEventLength) {
- return;
- }
-
- auto key = uint32_tAt(&msg[3]);
- bool key_down = msg[0];
- switch (key) {
- case cvd::xk::ControlLeft:
- case cvd::xk::ControlRight:
- control_key_down_ = key_down;
- break;
- case cvd::xk::MetaLeft:
- case cvd::xk::MetaRight:
- meta_key_down_ = key_down;
- break;
- case cvd::xk::F5:
- key = cvd::xk::Menu;
- break;
- case cvd::xk::F7:
- virtual_inputs_->PressPowerButton(key_down);
- return;
- default:
- break;
- }
-
- if (RotateIfIsRotationCommand(key)) {
- return;
- }
-
- virtual_inputs_->GenerateKeyPressEvent(key, key_down);
-}
-
-void VncClientConnection::HandleClientCutText() {
- auto msg = client_.Recv(kClientCutTextLength);
- if (msg.size() != kClientCutTextLength) {
- return;
- }
- auto len = uint32_tAt(&msg[3]);
- client_.Recv(len);
-}
-
-void VncClientConnection::NormalSession() {
- static constexpr std::uint8_t kSetPixelFormatMessage{0};
- static constexpr std::uint8_t kSetEncodingsMessage{2};
- static constexpr std::uint8_t kFramebufferUpdateRequestMessage{3};
- static constexpr std::uint8_t kKeyEventMessage{4};
- static constexpr std::uint8_t kPointerEventMessage{5};
- static constexpr std::uint8_t kClientCutTextMessage{6};
- while (true) {
- if (client_.closed()) {
- return;
- }
- auto msg = client_.Recv(1);
- if (client_.closed()) {
- return;
- }
- auto msg_type = msg.front();
- D("Received message type %d\n", static_cast<int>(msg_type));
-
- switch (msg_type) {
- case kSetPixelFormatMessage:
- HandleSetPixelFormat();
- break;
-
- case kSetEncodingsMessage:
- HandleSetEncodings();
- break;
-
- case kFramebufferUpdateRequestMessage:
- HandleFramebufferUpdateRequest();
- break;
-
- case kKeyEventMessage:
- HandleKeyEvent();
- break;
-
- case kPointerEventMessage:
- HandlePointerEvent();
- break;
-
- case kClientCutTextMessage:
- HandleClientCutText();
- break;
-
- default:
- ALOGW("message type not handled: %d", static_cast<int>(msg_type));
- break;
- }
- }
-}
diff --git a/guest/frontend/vnc_server/vnc_client_connection.h b/guest/frontend/vnc_server/vnc_client_connection.h
deleted file mode 100644
index e17eb96..0000000
--- a/guest/frontend/vnc_server/vnc_client_connection.h
+++ /dev/null
@@ -1,170 +0,0 @@
-#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 "blackboard.h"
-#include "virtual_inputs.h"
-#include "vnc_utils.h"
-
-#include "common/libs/tcp_socket/tcp_socket.h"
-
-#include <android-base/thread_annotations.h>
-#include <common/libs/fs/shared_fd.h>
-
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <vector>
-
-namespace cvd {
-namespace vnc {
-
-class VncClientConnection {
- public:
- VncClientConnection(ClientSocket client, 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;
- 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{8}, // depth
- std::uint8_t{}, // big_endian
- std::uint8_t{}, // true_color
- std::uint16_t{}, // red_max, (maxes not used when true color flag is 0)
- std::uint16_t{}, // green_max
- std::uint16_t{}, // blue_max
- std::uint8_t{}, // red_shift (shifts not used when true color flag is 0)
- std::uint8_t{}, // green_shift
- std::uint8_t{}, // blue_shift
- };
-
- bool supports_desktop_size_encoding_ = false;
- ScreenOrientation current_orientation_ GUARDED_BY(m_) =
- ScreenOrientation::Portrait;
-};
-
-} // namespace vnc
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/vnc_server.cpp b/guest/frontend/vnc_server/vnc_server.cpp
deleted file mode 100644
index ba23c45..0000000
--- a/guest/frontend/vnc_server/vnc_server.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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 "blackboard.h"
-#include "frame_buffer_watcher.h"
-#include "jpeg_compressor.h"
-#include "virtual_inputs.h"
-#include "vnc_client_connection.h"
-#include "vnc_server.h"
-#include "vnc_utils.h"
-
-#include "common/libs/tcp_socket/tcp_socket.h"
-
-using cvd::vnc::VncServer;
-
-VncServer::VncServer(int port, bool aggressive)
- : server_(port), frame_buffer_watcher_{&bb_}, aggressive_{aggressive} {}
-
-void VncServer::MainLoop() {
- while (true) {
- auto connection = server_.Accept();
- StartClient(std::move(connection));
- }
-}
-
-void VncServer::StartClient(ClientSocket sock) {
- std::thread t(&VncServer::StartClientThread, this, std::move(sock));
- t.detach();
-}
-
-void VncServer::StartClientThread(ClientSocket sock) {
- // NOTE if VncServer is expected to be destroyed, we have a problem here.
- // All of the client threads will be pointing to the VncServer's
- // data members. In the current setup, if the VncServer is destroyed with
- // clients still running, the clients will all be left with dangling
- // pointers.
- VncClientConnection client(std::move(sock), &virtual_inputs_, &bb_,
- aggressive_);
- client.StartSession();
-}
diff --git a/guest/frontend/vnc_server/vnc_server.h b/guest/frontend/vnc_server/vnc_server.h
deleted file mode 100644
index ed961ed..0000000
--- a/guest/frontend/vnc_server/vnc_server.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#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 "blackboard.h"
-#include "frame_buffer_watcher.h"
-#include "jpeg_compressor.h"
-#include "virtual_inputs.h"
-#include "vnc_client_connection.h"
-#include "vnc_utils.h"
-
-#include "common/libs/tcp_socket/tcp_socket.h"
-
-#include <thread>
-#include <string>
-#include <utility>
-
-
-
-namespace cvd {
-namespace vnc {
-
-class VncServer {
- public:
- explicit VncServer(int port, bool aggressive);
-
- VncServer(const VncServer&) = delete;
- VncServer& operator=(const VncServer&) = delete;
-
- [[noreturn]] void MainLoop();
-
- private:
- void StartClient(ClientSocket sock);
-
- void StartClientThread(ClientSocket sock);
-
- ServerSocket server_;
- VirtualInputs virtual_inputs_;
- BlackBoard bb_;
- FrameBufferWatcher frame_buffer_watcher_;
- bool aggressive_{};
-};
-
-} // namespace vnc
-} // namespace cvd
diff --git a/guest/frontend/vnc_server/vnc_utils.h b/guest/frontend/vnc_server/vnc_utils.h
deleted file mode 100644
index e25f860..0000000
--- a/guest/frontend/vnc_server/vnc_utils.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#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 <vector>
-#include <array>
-#include <utility>
-#include <cstdint>
-
-#include "common/libs/tcp_socket/tcp_socket.h"
-#include "common/vsoc/lib/fb_bcast_region_view.h"
-
-#undef D
-#ifdef VSOC_VNC_DEBUG
-#define D(...) ALOGD(__VA_ARGS__)
-#else
-#define D(...) ((void)0)
-#endif
-
-namespace cvd {
-namespace vnc {
-
-// TODO(haining) when the hwcomposer gives a sequence number type, use that
-// instead. It might just work to replace this class with a type alias
-// using StripeSeqNumber = whatever_the_hwcomposer_uses;
-class StripeSeqNumber {
- public:
- StripeSeqNumber() = default;
- explicit StripeSeqNumber(std::uint64_t t) : t_{t} {}
- bool operator<(const StripeSeqNumber& other) const {
- return t_ < other.t_;
- }
-
- bool operator<=(const StripeSeqNumber& other) const {
- return t_ <= other.t_;
- }
-
- private:
- std::uint64_t t_{};
-};
-
-constexpr int32_t kJpegMaxQualityEncoding = -23;
-constexpr int32_t kJpegMinQualityEncoding = -32;
-
-enum class ScreenOrientation { Portrait, Landscape };
-constexpr int kNumOrientations = 2;
-
-struct Stripe {
- int index = -1;
- std::uint64_t frame_id{};
- std::uint16_t x{};
- std::uint16_t y{};
- std::uint16_t width{};
- std::uint16_t height{};
- Message raw_data{};
- Message jpeg_data{};
- StripeSeqNumber seq_number{};
- ScreenOrientation orientation{};
-};
-
-inline constexpr int BytesPerPixel() {
- return sizeof(vsoc::framebuffer::FBBroadcastRegionView::Pixel);
-}
-
-// The width of the screen regardless of orientation. Does not change.
-inline int ActualScreenWidth() {
- return vsoc::framebuffer::FBBroadcastRegionView::GetInstance()->x_res();
-}
-
-// The height of the screen regardless of orientation. Does not change.
-inline int ActualScreenHeight() {
- return vsoc::framebuffer::FBBroadcastRegionView::GetInstance()->y_res();
-}
-
-inline int ScreenSizeInBytes() {
- return ActualScreenWidth() * ActualScreenHeight() * BytesPerPixel();
-}
-
-} // namespace vnc
-} // namespace cvd
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index 2cf3380..789004d 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -111,6 +111,13 @@
DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to"
" host kernel. This is only used during transition of our clients."
" Will be deprecated soon.");
+DEFINE_bool(start_vnc_server, true, "Whether to start the vnc server process.");
+DEFINE_string(vnc_server_binary,
+ StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
+ "/bin/vnc_server",
+ "Location of the vnc server binary.");
+DEFINE_int32(vnc_server_port, vsoc::GetPerInstanceDefault(6444),
+ "The port on which the vnc server should listen");
namespace {
const std::string kDataPolicyUseExisting = "use_existing";
@@ -242,7 +249,9 @@
KernelLogMonitor& operator=(const KernelLogMonitor&) = delete;
};
-void subprocess(const char* const* command, const char* const* envp) {
+void subprocess(const char* const* command,
+ const char* const* envp,
+ bool wait_for_child = true) {
pid_t pid = fork();
if (!pid) {
int rval = execve(command[0], const_cast<char* const*>(command),
@@ -255,8 +264,13 @@
if (pid == -1) {
LOG(ERROR) << "fork of " << command[0] << " failed (" << strerror(errno)
<< ")";
- } else {
- waitpid(pid, 0, 0);
+ }
+ if (pid > 0) {
+ if (wait_for_child) {
+ waitpid(pid, 0, 0);
+ } else {
+ LOG(INFO) << "Started " << command[0] << ", pid: " << pid;
+ }
}
}
@@ -454,5 +468,13 @@
if (exit_code) {
LOG(FATAL) << "Launch command exited with status " << exit_code;
}
+
+ if (FLAGS_start_vnc_server) {
+ // Launch the vnc server, don't wait for it to complete
+ auto port_options = "-port=" + std::to_string(FLAGS_vnc_server_port);
+ const char* vnc_command[] = {FLAGS_vnc_server_binary.c_str(),
+ port_options.c_str(), NULL};
+ subprocess(vnc_command, NULL, false);
+ }
pause();
}
diff --git a/host/frontend/vnc_server/Android.bp b/host/frontend/vnc_server/Android.bp
index 66db3f6..dc65687 100644
--- a/host/frontend/vnc_server/Android.bp
+++ b/host/frontend/vnc_server/Android.bp
@@ -22,7 +22,6 @@
"main.cpp",
"simulated_hw_composer.cpp",
"virtual_inputs.cpp",
- "virtual_input_device.cpp",
"vnc_client_connection.cpp",
"vnc_server.cpp",
"vnc_utils.cpp",
diff --git a/host/frontend/vnc_server/simulated_hw_composer.cpp b/host/frontend/vnc_server/simulated_hw_composer.cpp
index 001006b..53e00b7 100644
--- a/host/frontend/vnc_server/simulated_hw_composer.cpp
+++ b/host/frontend/vnc_server/simulated_hw_composer.cpp
@@ -16,13 +16,13 @@
#include "host/frontend/vnc_server/simulated_hw_composer.h"
-#include "common/vsoc/lib/typed_region_view.h"
#include "host/frontend/vnc_server/vnc_utils.h"
#include "host/libs/config/host_config.h"
-#include "host/vsoc/lib/gralloc_buffer_region_view.h"
+#include "common/vsoc/lib/framebuffer_region_view.h"
using cvd::vnc::SimulatedHWComposer;
-using vsoc::gralloc::GrallocBufferRegionView;
+using vsoc::framebuffer::FrameBufferRegionView;
+using vsoc::framebuffer::FBBroadcastRegionView;
SimulatedHWComposer::SimulatedHWComposer(BlackBoard* bb)
:
@@ -77,12 +77,12 @@
std::uint64_t stripe_seq_num = 1;
while (!closed()) {
bb_->WaitForAtLeastOneClientConnection();
- vsoc_reg_off_t buffer_offset =
- GetFBBroadcastRegionView()->WaitForNewFrameSince(&previous_seq_num);
-
- const auto* frame_start =
- GrallocBufferRegionView::GetInstance(vsoc::GetDomain().c_str())
- ->OffsetToBufferPtr(buffer_offset);
+ uint32_t offset =
+ FBBroadcastRegionView::GetInstance(vsoc::GetDomain().c_str())
+ ->WaitForNewFrameSince(&previous_seq_num);
+ const char* frame_start = static_cast<char*>(
+ FrameBufferRegionView::GetInstance(vsoc::GetDomain().c_str())
+ ->GetBufferFromOffset(offset));
raw_screen.assign(frame_start, frame_start + ScreenSizeInBytes());
for (int i = 0; i < kNumStripes; ++i) {
diff --git a/host/frontend/vnc_server/virtual_input_device.cpp b/host/frontend/vnc_server/virtual_input_device.cpp
deleted file mode 100644
index eacec38..0000000
--- a/host/frontend/vnc_server/virtual_input_device.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2014 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 "host/frontend/vnc_server/virtual_input_device.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/input.h>
-#include <linux/uinput.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <vector>
-
-#include <glog/logging.h>
-#include "host/frontend/vnc_server/keysyms.h"
-
-namespace cvd {
-
-//////////////////////////
-// VirtualButton Support
-//////////////////////////
-
-void VirtualButton::HandleButtonPressEvent(bool /*button_down*/) {
- SendCommand(std::string("key ") + "down " + input_keycode_ + "\n");
-}
-
-//////////////////////////
-// VirtualKeyboard Support
-//////////////////////////
-
-struct KeyEventToInput {
- uint32_t xk;
- std::string input_code;
-};
-
-static const KeyEventToInput key_table[] = {
- {xk::AltLeft, "KEYCODE_ALT_LEFT"},
- {xk::ControlLeft, "KEYCODE_CTRL_LEFT"},
- {xk::ShiftLeft, "KEYCODE_SHIFT_LEFT"},
- {xk::AltRight, "KEYCODE_ALT_RIGHT"},
- {xk::ControlRight, "KEYCODE_CTRL_RIGHT"},
- {xk::ShiftRight, "KEYCODE_SHIFT_RIGHT"},
- {xk::MetaLeft, "KEYCODE_META_LEFT"},
- {xk::MetaRight, "KEYCODE_META_RIGHT"},
- // {xk::MultiKey, "KEYCODE_COMPOSE"},
-
- {xk::CapsLock, "KEYCODE_CAPS_LOCK"},
- {xk::NumLock, "KEYCODE_NUM_LOCK"},
- {xk::ScrollLock, "KEYCODE_SCROLL_LOCK"},
-
- {xk::BackSpace, "KEYCODE_DEL"},
- {xk::Tab, "KEYCODE_TAB"},
- {xk::Return, "KEYCODE_ENTER"},
- {xk::Escape, "KEYCODE_ESCAPE"},
-
- {' ', "KEYCODE_SPACE"},
- {'!', "KEYCODE_1"},
- {'"', "KEYCODE_APOSTROPHE"},
- {'#', "KEYCODE_POUND"},
- {'$', "KEYCODE_4"},
- {'%', "KEYCODE_5"},
- {'^', "KEYCODE_6"},
- {'&', "KEYCODE_7"},
- {'\'', "KEYCODE_APOSTROPHE"},
- {'(', "KEYCODE_NUMPAD_LEFT_PAREN"},
- {')', "KEYCODE_NUMPAD_RIGHT_PAREN"},
- {'*', "KEYCODE_STAR"},
- {'+', "KEYCODE_EQUALS"},
- {',', "KEYCODE_COMMA"},
- {'-', "KEYCODE_MINUS"},
- {'.', "KEYCODE_PERIOD"},
- {'/', "KEYCODE_SLASH"},
- {'0', "KEYCODE_0"},
- {'1', "KEYCODE_1"},
- {'2', "KEYCODE_2"},
- {'3', "KEYCODE_3"},
- {'4', "KEYCODE_4"},
- {'5', "KEYCODE_5"},
- {'6', "KEYCODE_6"},
- {'7', "KEYCODE_7"},
- {'8', "KEYCODE_8"},
- {'9', "KEYCODE_9"},
- {':', "KEYCODE_SEMICOLON"},
- {';', "KEYCODE_SEMICOLON"},
- {'<', "KEYCODE_COMMA"},
- {'=', "KEYCODE_EQUALS"},
- {'>', "KEYCODE_PERIOD"},
- {'?', "KEYCODE_SLASH"},
- {'@', "KEYCODE_2"},
- {'A', "KEYCODE_A"},
- {'B', "KEYCODE_B"},
- {'C', "KEYCODE_C"},
- {'D', "KEYCODE_D"},
- {'E', "KEYCODE_E"},
- {'F', "KEYCODE_F"},
- {'G', "KEYCODE_G"},
- {'H', "KEYCODE_H"},
- {'I', "KEYCODE_I"},
- {'J', "KEYCODE_J"},
- {'K', "KEYCODE_K"},
- {'L', "KEYCODE_L"},
- {'M', "KEYCODE_M"},
- {'N', "KEYCODE_N"},
- {'O', "KEYCODE_O"},
- {'P', "KEYCODE_P"},
- {'Q', "KEYCODE_Q"},
- {'R', "KEYCODE_R"},
- {'S', "KEYCODE_S"},
- {'T', "KEYCODE_T"},
- {'U', "KEYCODE_U"},
- {'V', "KEYCODE_V"},
- {'W', "KEYCODE_W"},
- {'X', "KEYCODE_X"},
- {'Y', "KEYCODE_Y"},
- {'Z', "KEYCODE_Z"},
- {'[', "KEYCODE_LEFT_BRACKET"},
- {'\\', "KEYCODE_BACKSLASH"},
- {']', "KEYCODE_RIGHT_BRACKET"},
- {'-', "KEYCODE_MINUS"},
- {'_', "KEYCODE_MINUS"},
- {'`', "KEYCODE_GRAVE"},
- {'a', "KEYCODE_A"},
- {'b', "KEYCODE_B"},
- {'c', "KEYCODE_C"},
- {'d', "KEYCODE_D"},
- {'e', "KEYCODE_E"},
- {'f', "KEYCODE_F"},
- {'g', "KEYCODE_G"},
- {'h', "KEYCODE_H"},
- {'i', "KEYCODE_I"},
- {'j', "KEYCODE_J"},
- {'k', "KEYCODE_K"},
- {'l', "KEYCODE_L"},
- {'m', "KEYCODE_M"},
- {'n', "KEYCODE_N"},
- {'o', "KEYCODE_O"},
- {'p', "KEYCODE_P"},
- {'q', "KEYCODE_Q"},
- {'r', "KEYCODE_R"},
- {'s', "KEYCODE_S"},
- {'t', "KEYCODE_T"},
- {'u', "KEYCODE_U"},
- {'v', "KEYCODE_V"},
- {'w', "KEYCODE_W"},
- {'x', "KEYCODE_X"},
- {'y', "KEYCODE_Y"},
- {'z', "KEYCODE_Z"},
- {'{', "KEYCODE_LEFT_BRACKET"},
- {'\\', "KEYCODE_BACKSLASH"},
- // {'|', "|"},
- {'}', "KEYCODE_RIGHT_BRACKET"},
- {'~', "KEYCODE_GRAVE"},
-
- {xk::F1, "KEYCODE_F1"},
- {xk::F2, "KEYCODE_F2"},
- {xk::F3, "KEYCODE_F3"},
- {xk::F4, "KEYCODE_F4"},
- {xk::F5, "KEYCODE_F5"},
- {xk::F6, "KEYCODE_F6"},
- {xk::F7, "KEYCODE_F7"},
- {xk::F8, "KEYCODE_F8"},
- {xk::F9, "KEYCODE_F9"},
- {xk::F10, "KEYCODE_F10"},
- {xk::F11, "KEYCODE_F11"},
- {xk::F12, "KEYCODE_F12"},
- // {xk::F13, "KEYCODE_F13"},
- // {xk::F14, "KEYCODE_F14"},
- // {xk::F15, "KEYCODE_F15"},
- // {xk::F16, "KEYCODE_F16"},
- // {xk::F17, "KEYCODE_F17"},
- // {xk::F18, "KEYCODE_F18"},
- // {xk::F19, "KEYCODE_F19"},
- // {xk::F20, "KEYCODE_F20"},
- // {xk::F21, "KEYCODE_F21"},
- // {xk::F22, "KEYCODE_F22"},
- // {xk::F23, "KEYCODE_F23"},
- // {xk::F24, "KEYCODE_F24"},
-
- {xk::Keypad0, "KEYCODE_NUMPAD_0"},
- {xk::Keypad1, "KEYCODE_NUMPAD_1"},
- {xk::Keypad2, "KEYCODE_NUMPAD_2"},
- {xk::Keypad3, "KEYCODE_NUMPAD_3"},
- {xk::Keypad4, "KEYCODE_NUMPAD_4"},
- {xk::Keypad5, "KEYCODE_NUMPAD_5"},
- {xk::Keypad6, "KEYCODE_NUMPAD_6"},
- {xk::Keypad7, "KEYCODE_NUMPAD_7"},
- {xk::Keypad8, "KEYCODE_NUMPAD_8"},
- {xk::Keypad9, "KEYCODE_NUMPAD_9"},
- {xk::KeypadMultiply, "KEYCODE_NUMPAD_MULTIPLY"},
- {xk::KeypadSubtract, "KEYCODE_NUMPAD_SUBTRACT"},
- {xk::KeypadAdd, "KEYCODE_NUMPAD_ADD"},
- {xk::KeypadDecimal, "KEYCODE_NUMPAD_DOT"},
- {xk::KeypadEnter, "KEYCODE_NUMPAD_ENTER"},
- {xk::KeypadDivide, "KEYCODE_NUMPAD_DIVIDE"},
- {xk::KeypadEqual, "KEYCODE_NUMPAD_EQUALS"},
- // {xk::PlusMinus, "KEYCODE_NUMPAD_PLUSMINUS"},
-
- {xk::SysReq, "KEYCODE_SYSRQ"},
- // {xk::LineFeed, "KEYCODE_LINEFEED"},
- {xk::Home, "KEYCODE_HOME"},
- {xk::Up, "KEYCODE_DPAD_UP"},
- {xk::PageUp, "KEYCODE_PAGE_UP"},
- {xk::Left, "KEYCODE_DPAD_LEFT"},
- {xk::Right, "KEYCODE_DPAD_RIGHT"},
- {xk::End, "KEYCODE_MOVE_END"},
- {xk::Down, "KEYCODE_DPAD_DOWN"},
- {xk::PageDown, "KEYCODE_PAGE_DOWN"},
- {xk::Insert, "KEYCODE_INSERT"},
- {xk::Delete, "KEYCODE_FORWARD_DEL"},
- {xk::Pause, "KEYCODE_BREAK"},
- {xk::KeypadSeparator, "KEYCODE_NUMPAD_COMMA"},
- {xk::Yen, "KEYCODE_YEN"},
- // {xk::Cancel, "KEYCODE_STOP"},
- // {xk::Redo, "KEYCODE_AGAIN"},
- // {xk::Undo, "KEYCODE_UNDO"},
- // {xk::Find, "KEYCODE_FIND"},
- // {xk::Print, "KEYCODE_PRINT"},
- {xk::VolumeDown, "KEYCODE_VOLUME_DOWN"},
- {xk::Mute, "KEYCODE_MUTE"},
- {xk::VolumeUp, "KEYCODE_VOLUME_UP"},
- {xk::Menu, "KEYCODE_MENU"},
- {xk::VNCMenu, "KEYCODE_MENU"},
-};
-
-VirtualKeyboard::VirtualKeyboard(std::function<bool(std::string)> cmd_sender)
- : VirtualInputDevice(cmd_sender) {
- for (const auto& key : key_table) {
- keymapping_[key.xk] = key.input_code;
- }
-}
-
-void VirtualKeyboard::GenerateKeyPressEvent(int keycode, bool button_down) {
- if (keymapping_.count(keycode)) {
- SendCommand(std::string("key ") + (button_down ? "down " : "up ") +
- keymapping_[keycode] + "\n");
- } else {
- LOG(INFO) << "Unknown keycode " << keycode;
- }
-}
-
-//////////////////////////
-// VirtualTouchPad Support
-//////////////////////////
-
-std::string VirtualTouchPad::GetCommand(bool touch_down, int x, int y) {
- std::string cmd;
- if (touch_down == prev_touch_) {
- if (touch_down && (x != prev_x_ || y != prev_y_)) {
- cmd = "touch move ";
- } // else don't repeat last event or send non touch mouse movements
- } else if (touch_down) {
- cmd = "touch down ";
- } else {
- cmd = "touch up ";
- }
- prev_touch_ = touch_down;
- prev_x_ = x;
- prev_y_ = y;
- return cmd;
-}
-
-void VirtualTouchPad::HandlePointerEvent(bool touch_down, int x, int y) {
- SendCommand(GetCommand(touch_down, x, y) + std::to_string(x) + " " +
- std::to_string(y) + "\n");
-}
-
-} // namespace cvd
diff --git a/host/frontend/vnc_server/virtual_input_device.h b/host/frontend/vnc_server/virtual_input_device.h
deleted file mode 100644
index 5fb0be5..0000000
--- a/host/frontend/vnc_server/virtual_input_device.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#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 <functional>
-#include <map>
-#include <string>
-
-namespace cvd {
-
-// Base virtual input device class which contains a bunch of boiler-plate code.
-class VirtualInputDevice {
- public:
- VirtualInputDevice(std::function<bool(std::string)> cmd_sender)
- : send_command_(cmd_sender) {}
-
- protected:
- bool SendCommand(std::string cmd) { return send_command_(cmd); }
-
- private:
- std::function<bool(std::string)> send_command_;
-};
-
-// Virtual touch-pad.
-class VirtualTouchPad : public VirtualInputDevice {
- public:
- VirtualTouchPad(std::function<bool(std::string)> cmd_sender)
- : VirtualInputDevice(cmd_sender) {}
-
- void HandlePointerEvent(bool touch_down, int x, int y);
-
- private:
- std::string GetCommand(bool touch_down, int x, int y);
- bool prev_touch_ = false;
- int prev_x_ = -1;
- int prev_y_ = -1;
-};
-
-// Virtual button.
-class VirtualButton : public VirtualInputDevice {
- public:
- VirtualButton(std::string input_keycode,
- std::function<bool(std::string)> cmd_sender)
- : VirtualInputDevice(cmd_sender), input_keycode_(input_keycode) {}
-
- void HandleButtonPressEvent(bool button_down);
-
- private:
- std::string input_keycode_;
-};
-
-// Virtual keyboard.
-class VirtualKeyboard : public VirtualInputDevice {
- public:
- VirtualKeyboard(std::function<bool(std::string)> cmd_sender);
- virtual ~VirtualKeyboard() {}
-
- void GenerateKeyPressEvent(int code, bool down);
-
- private:
- std::map<uint32_t, std::string> keymapping_;
-};
-
-} // namespace cvd
diff --git a/host/frontend/vnc_server/virtual_inputs.cpp b/host/frontend/vnc_server/virtual_inputs.cpp
index 30f8638..6cb06dc 100644
--- a/host/frontend/vnc_server/virtual_inputs.cpp
+++ b/host/frontend/vnc_server/virtual_inputs.cpp
@@ -16,65 +16,228 @@
#include "host/frontend/vnc_server/virtual_inputs.h"
#include <gflags/gflags.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
#include <mutex>
-#include <thread>
+#include "keysyms.h"
-DEFINE_string(input_socket, "/tmp/android-cuttlefish-1-input",
- "The name of unix socket where the monkey server is listening "
- "for input commands");
using cvd::vnc::VirtualInputs;
-
-VirtualInputs::VirtualInputs()
- : virtual_keyboard_(
- [this](std::string cmd) { return SendMonkeyComand(cmd); }),
- virtual_touch_pad_(
- [this](std::string cmd) { return SendMonkeyComand(cmd); }),
- virtual_power_button_("KEYCODE_POWER", [this](std::string cmd) {
- return SendMonkeyComand(cmd);
- }) {
- monkey_socket_ = cvd::SharedFD::SocketLocalClient(FLAGS_input_socket.c_str(),
- false, SOCK_STREAM);
- if (!monkey_socket_->IsOpen()) {
- // Monkey is known to die on the second conection, so let's wait a litttle
- // bit and try again.
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- monkey_socket_ = cvd::SharedFD::SocketLocalClient(
- FLAGS_input_socket.c_str(), false, SOCK_STREAM);
- if (!monkey_socket_->IsOpen()) {
- LOG(FATAL) << "Unable to connect to the mokey server";
- }
- }
-}
+using vsoc::input_events::InputEventsRegionView;
namespace {
-constexpr char kCmdDone[] = "done\n";
-} // anonymous namespace
+void AddKeyMappings(std::map<uint32_t, uint32_t>* key_mapping) {
+ (*key_mapping)[cvd::xk::AltLeft] = KEY_LEFTALT;
+ (*key_mapping)[cvd::xk::ControlLeft] = KEY_LEFTCTRL;
+ (*key_mapping)[cvd::xk::ShiftLeft] = KEY_LEFTSHIFT;
+ (*key_mapping)[cvd::xk::AltRight] = KEY_RIGHTALT;
+ (*key_mapping)[cvd::xk::ControlRight] = KEY_RIGHTCTRL;
+ (*key_mapping)[cvd::xk::ShiftRight] = KEY_RIGHTSHIFT;
+ (*key_mapping)[cvd::xk::MetaLeft] = KEY_LEFTMETA;
+ (*key_mapping)[cvd::xk::MetaRight] = KEY_RIGHTMETA;
+ (*key_mapping)[cvd::xk::MultiKey] = KEY_COMPOSE;
-VirtualInputs::~VirtualInputs() {
- if (monkey_socket_->IsOpen()) {
- monkey_socket_->Send(kCmdDone, sizeof(kCmdDone) - 1, 0);
+ (*key_mapping)[cvd::xk::CapsLock] = KEY_CAPSLOCK;
+ (*key_mapping)[cvd::xk::NumLock] = KEY_NUMLOCK;
+ (*key_mapping)[cvd::xk::ScrollLock] = KEY_SCROLLLOCK;
+
+ (*key_mapping)[cvd::xk::BackSpace] = KEY_BACKSPACE;
+ (*key_mapping)[cvd::xk::Tab] = KEY_TAB;
+ (*key_mapping)[cvd::xk::Return] = KEY_ENTER;
+ (*key_mapping)[cvd::xk::Escape] = KEY_ESC;
+
+ (*key_mapping)[' '] = KEY_SPACE;
+ (*key_mapping)['!'] = KEY_1;
+ (*key_mapping)['"'] = KEY_APOSTROPHE;
+ (*key_mapping)['#'] = KEY_3;
+ (*key_mapping)['$'] = KEY_4;
+ (*key_mapping)['%'] = KEY_5;
+ (*key_mapping)['^'] = KEY_6;
+ (*key_mapping)['&'] = KEY_7;
+ (*key_mapping)['\''] = KEY_APOSTROPHE;
+ (*key_mapping)['('] = KEY_9;
+ (*key_mapping)[')'] = KEY_0;
+ (*key_mapping)['*'] = KEY_8;
+ (*key_mapping)['+'] = KEY_EQUAL;
+ (*key_mapping)[','] = KEY_COMMA;
+ (*key_mapping)['-'] = KEY_MINUS;
+ (*key_mapping)['.'] = KEY_DOT;
+ (*key_mapping)['/'] = KEY_SLASH;
+ (*key_mapping)['0'] = KEY_0;
+ (*key_mapping)['1'] = KEY_1;
+ (*key_mapping)['2'] = KEY_2;
+ (*key_mapping)['3'] = KEY_3;
+ (*key_mapping)['4'] = KEY_4;
+ (*key_mapping)['5'] = KEY_5;
+ (*key_mapping)['6'] = KEY_6;
+ (*key_mapping)['7'] = KEY_7;
+ (*key_mapping)['8'] = KEY_8;
+ (*key_mapping)['9'] = KEY_9;
+ (*key_mapping)[':'] = KEY_SEMICOLON;
+ (*key_mapping)[';'] = KEY_SEMICOLON;
+ (*key_mapping)['<'] = KEY_COMMA;
+ (*key_mapping)['='] = KEY_EQUAL;
+ (*key_mapping)['>'] = KEY_DOT;
+ (*key_mapping)['?'] = KEY_SLASH;
+ (*key_mapping)['@'] = KEY_2;
+ (*key_mapping)['A'] = KEY_A;
+ (*key_mapping)['B'] = KEY_B;
+ (*key_mapping)['C'] = KEY_C;
+ (*key_mapping)['D'] = KEY_D;
+ (*key_mapping)['E'] = KEY_E;
+ (*key_mapping)['F'] = KEY_F;
+ (*key_mapping)['G'] = KEY_G;
+ (*key_mapping)['H'] = KEY_H;
+ (*key_mapping)['I'] = KEY_I;
+ (*key_mapping)['J'] = KEY_J;
+ (*key_mapping)['K'] = KEY_K;
+ (*key_mapping)['L'] = KEY_L;
+ (*key_mapping)['M'] = KEY_M;
+ (*key_mapping)['N'] = KEY_N;
+ (*key_mapping)['O'] = KEY_O;
+ (*key_mapping)['P'] = KEY_P;
+ (*key_mapping)['Q'] = KEY_Q;
+ (*key_mapping)['R'] = KEY_R;
+ (*key_mapping)['S'] = KEY_S;
+ (*key_mapping)['T'] = KEY_T;
+ (*key_mapping)['U'] = KEY_U;
+ (*key_mapping)['V'] = KEY_V;
+ (*key_mapping)['W'] = KEY_W;
+ (*key_mapping)['X'] = KEY_X;
+ (*key_mapping)['Y'] = KEY_Y;
+ (*key_mapping)['Z'] = KEY_Z;
+ (*key_mapping)['['] = KEY_LEFTBRACE;
+ (*key_mapping)['\\'] = KEY_BACKSLASH;
+ (*key_mapping)[']'] = KEY_RIGHTBRACE;
+ (*key_mapping)['-'] = KEY_MINUS;
+ (*key_mapping)['_'] = KEY_MINUS;
+ (*key_mapping)['`'] = KEY_GRAVE;
+ (*key_mapping)['a'] = KEY_A;
+ (*key_mapping)['b'] = KEY_B;
+ (*key_mapping)['c'] = KEY_C;
+ (*key_mapping)['d'] = KEY_D;
+ (*key_mapping)['e'] = KEY_E;
+ (*key_mapping)['f'] = KEY_F;
+ (*key_mapping)['g'] = KEY_G;
+ (*key_mapping)['h'] = KEY_H;
+ (*key_mapping)['i'] = KEY_I;
+ (*key_mapping)['j'] = KEY_J;
+ (*key_mapping)['k'] = KEY_K;
+ (*key_mapping)['l'] = KEY_L;
+ (*key_mapping)['m'] = KEY_M;
+ (*key_mapping)['n'] = KEY_N;
+ (*key_mapping)['o'] = KEY_O;
+ (*key_mapping)['p'] = KEY_P;
+ (*key_mapping)['q'] = KEY_Q;
+ (*key_mapping)['r'] = KEY_R;
+ (*key_mapping)['s'] = KEY_S;
+ (*key_mapping)['t'] = KEY_T;
+ (*key_mapping)['u'] = KEY_U;
+ (*key_mapping)['v'] = KEY_V;
+ (*key_mapping)['w'] = KEY_W;
+ (*key_mapping)['x'] = KEY_X;
+ (*key_mapping)['y'] = KEY_Y;
+ (*key_mapping)['z'] = KEY_Z;
+ (*key_mapping)['{'] = KEY_LEFTBRACE;
+ (*key_mapping)['\\'] = KEY_BACKSLASH;
+ (*key_mapping)['|'] = KEY_BACKSLASH;
+ (*key_mapping)['}'] = KEY_RIGHTBRACE;
+ (*key_mapping)['~'] = KEY_GRAVE;
+
+ (*key_mapping)[cvd::xk::F1] = KEY_F1;
+ (*key_mapping)[cvd::xk::F2] = KEY_F2;
+ (*key_mapping)[cvd::xk::F3] = KEY_F3;
+ (*key_mapping)[cvd::xk::F4] = KEY_F4;
+ (*key_mapping)[cvd::xk::F5] = KEY_F5;
+ (*key_mapping)[cvd::xk::F6] = KEY_F6;
+ (*key_mapping)[cvd::xk::F7] = KEY_F7;
+ (*key_mapping)[cvd::xk::F8] = KEY_F8;
+ (*key_mapping)[cvd::xk::F9] = KEY_F9;
+ (*key_mapping)[cvd::xk::F10] = KEY_F10;
+ (*key_mapping)[cvd::xk::F11] = KEY_F11;
+ (*key_mapping)[cvd::xk::F12] = KEY_F12;
+ (*key_mapping)[cvd::xk::F13] = KEY_F13;
+ (*key_mapping)[cvd::xk::F14] = KEY_F14;
+ (*key_mapping)[cvd::xk::F15] = KEY_F15;
+ (*key_mapping)[cvd::xk::F16] = KEY_F16;
+ (*key_mapping)[cvd::xk::F17] = KEY_F17;
+ (*key_mapping)[cvd::xk::F18] = KEY_F18;
+ (*key_mapping)[cvd::xk::F19] = KEY_F19;
+ (*key_mapping)[cvd::xk::F20] = KEY_F20;
+ (*key_mapping)[cvd::xk::F21] = KEY_F21;
+ (*key_mapping)[cvd::xk::F22] = KEY_F22;
+ (*key_mapping)[cvd::xk::F23] = KEY_F23;
+ (*key_mapping)[cvd::xk::F24] = KEY_F24;
+
+ (*key_mapping)[cvd::xk::Keypad0] = KEY_KP0;
+ (*key_mapping)[cvd::xk::Keypad1] = KEY_KP1;
+ (*key_mapping)[cvd::xk::Keypad2] = KEY_KP2;
+ (*key_mapping)[cvd::xk::Keypad3] = KEY_KP3;
+ (*key_mapping)[cvd::xk::Keypad4] = KEY_KP4;
+ (*key_mapping)[cvd::xk::Keypad5] = KEY_KP5;
+ (*key_mapping)[cvd::xk::Keypad6] = KEY_KP6;
+ (*key_mapping)[cvd::xk::Keypad7] = KEY_KP7;
+ (*key_mapping)[cvd::xk::Keypad8] = KEY_KP8;
+ (*key_mapping)[cvd::xk::Keypad9] = KEY_KP9;
+ (*key_mapping)[cvd::xk::KeypadMultiply] = KEY_KPASTERISK;
+ (*key_mapping)[cvd::xk::KeypadSubtract] = KEY_KPMINUS;
+ (*key_mapping)[cvd::xk::KeypadAdd] = KEY_KPPLUS;
+ (*key_mapping)[cvd::xk::KeypadDecimal] = KEY_KPDOT;
+ (*key_mapping)[cvd::xk::KeypadEnter] = KEY_KPENTER;
+ (*key_mapping)[cvd::xk::KeypadDivide] = KEY_KPSLASH;
+ (*key_mapping)[cvd::xk::KeypadEqual] = KEY_KPEQUAL;
+ (*key_mapping)[cvd::xk::PlusMinus] = KEY_KPPLUSMINUS;
+
+ (*key_mapping)[cvd::xk::SysReq] = KEY_SYSRQ;
+ (*key_mapping)[cvd::xk::LineFeed] = KEY_LINEFEED;
+ (*key_mapping)[cvd::xk::Home] = KEY_HOME;
+ (*key_mapping)[cvd::xk::Up] = KEY_UP;
+ (*key_mapping)[cvd::xk::PageUp] = KEY_PAGEUP;
+ (*key_mapping)[cvd::xk::Left] = KEY_LEFT;
+ (*key_mapping)[cvd::xk::Right] = KEY_RIGHT;
+ (*key_mapping)[cvd::xk::End] = KEY_END;
+ (*key_mapping)[cvd::xk::Down] = KEY_DOWN;
+ (*key_mapping)[cvd::xk::PageDown] = KEY_PAGEDOWN;
+ (*key_mapping)[cvd::xk::Insert] = KEY_INSERT;
+ (*key_mapping)[cvd::xk::Delete] = KEY_DELETE;
+ (*key_mapping)[cvd::xk::Pause] = KEY_PAUSE;
+ (*key_mapping)[cvd::xk::KeypadSeparator] = KEY_KPCOMMA;
+ (*key_mapping)[cvd::xk::Yen] = KEY_YEN;
+ (*key_mapping)[cvd::xk::Cancel] = KEY_STOP;
+ (*key_mapping)[cvd::xk::Redo] = KEY_AGAIN;
+ (*key_mapping)[cvd::xk::Undo] = KEY_UNDO;
+ (*key_mapping)[cvd::xk::Find] = KEY_FIND;
+ (*key_mapping)[cvd::xk::Print] = KEY_PRINT;
+ (*key_mapping)[cvd::xk::VolumeDown] = KEY_VOLUMEDOWN;
+ (*key_mapping)[cvd::xk::Mute] = KEY_MUTE;
+ (*key_mapping)[cvd::xk::VolumeUp] = KEY_VOLUMEUP;
+ (*key_mapping)[cvd::xk::Menu] = KEY_MENU;
+ (*key_mapping)[cvd::xk::VNCMenu] = KEY_MENU;
+}
+} // namespace
+
+VirtualInputs::VirtualInputs() {
+ input_events_region_view_ =
+ vsoc::input_events::InputEventsRegionView::GetInstance(
+ vsoc::GetDomain().c_str());
+ if (!input_events_region_view_) {
+ LOG(FATAL) << "Failed to open Input events region view";
}
+ AddKeyMappings(&keymapping_);
}
-bool VirtualInputs::SendMonkeyComand(std::string cmd) {
- return static_cast<size_t>(
- monkey_socket_->Send(cmd.c_str(), cmd.size(), 0)) == cmd.size();
- // TODO(jemoreira): If monkey is going to be used for a long time it may be
- // useful to check the response to this commands.
-}
-
-void VirtualInputs::GenerateKeyPressEvent(int code, bool down) {
- std::lock_guard<std::mutex> guard(m_);
- virtual_keyboard_.GenerateKeyPressEvent(code, down);
+void VirtualInputs::GenerateKeyPressEvent(int key_code, bool down) {
+ if (keymapping_.count(key_code)) {
+ input_events_region_view_->HandleKeyboardEvent(down, keymapping_[key_code]);
+ } else {
+ LOG(INFO) << "Unknown keycode" << key_code;
+ }
}
void VirtualInputs::PressPowerButton(bool down) {
- std::lock_guard<std::mutex> guard(m_);
- virtual_power_button_.HandleButtonPressEvent(down);
+ input_events_region_view_->HandlePowerButtonEvent(down);
}
void VirtualInputs::HandlePointerEvent(bool touch_down, int x, int y) {
- std::lock_guard<std::mutex> guard(m_);
- virtual_touch_pad_.HandlePointerEvent(touch_down, x, y);
+ input_events_region_view_->HandleSingleTouchEvent(touch_down, x, y);
}
diff --git a/host/frontend/vnc_server/virtual_inputs.h b/host/frontend/vnc_server/virtual_inputs.h
index d5d00b9..27c8ccf 100644
--- a/host/frontend/vnc_server/virtual_inputs.h
+++ b/host/frontend/vnc_server/virtual_inputs.h
@@ -16,14 +16,12 @@
* limitations under the License.
*/
-#include <linux/input.h>
+#include "vnc_utils.h"
+#include <map>
#include <mutex>
-#include "common/libs/fs/shared_fd.h"
-#include "common/libs/threads/thread_annotations.h"
-#include "host/frontend/vnc_server/virtual_input_device.h"
-#include "host/frontend/vnc_server/vnc_utils.h"
+#include "common/vsoc/lib/input_events_region_view.h"
namespace cvd {
namespace vnc {
@@ -31,19 +29,15 @@
class VirtualInputs {
public:
VirtualInputs();
- ~VirtualInputs();
void GenerateKeyPressEvent(int code, bool down);
void PressPowerButton(bool down);
void HandlePointerEvent(bool touch_down, int x, int y);
private:
- cvd::SharedFD monkey_socket_;
- bool SendMonkeyComand(std::string cmd);
- std::mutex m_;
- VirtualKeyboard virtual_keyboard_ GUARDED_BY(m_);
- VirtualTouchPad virtual_touch_pad_ GUARDED_BY(m_);
- VirtualButton virtual_power_button_ GUARDED_BY(m_);
+ std::shared_ptr<vsoc::input_events::InputEventsRegionView>
+ input_events_region_view_;
+ std::map<uint32_t, uint32_t> keymapping_;
};
} // namespace vnc
diff --git a/host/frontend/vnc_server/vnc_client_connection.cpp b/host/frontend/vnc_server/vnc_client_connection.cpp
index da94600..acbdfaa 100644
--- a/host/frontend/vnc_server/vnc_client_connection.cpp
+++ b/host/frontend/vnc_server/vnc_client_connection.cpp
@@ -41,6 +41,7 @@
using cvd::vnc::Stripe;
using cvd::vnc::StripePtrVec;
using cvd::vnc::VncClientConnection;
+using vsoc::framebuffer::FBBroadcastRegionView;
DEFINE_bool(debug_client, false, "Turn on detailed logging for the client");
@@ -143,18 +144,18 @@
}
std::uint32_t RedVal(std::uint32_t pixel) {
- return (pixel >> GceFrameBuffer::kRedShift) &
- ((0x1 << GceFrameBuffer::kRedBits) - 1);
+ return (pixel >> FBBroadcastRegionView::kRedShift) &
+ ((0x1 << FBBroadcastRegionView::kRedBits) - 1);
}
std::uint32_t BlueVal(std::uint32_t pixel) {
- return (pixel >> GceFrameBuffer::kBlueShift) &
- ((0x1 << GceFrameBuffer::kBlueBits) - 1);
+ return (pixel >> FBBroadcastRegionView::kBlueShift) &
+ ((0x1 << FBBroadcastRegionView::kBlueBits) - 1);
}
std::uint32_t GreenVal(std::uint32_t pixel) {
- return (pixel >> GceFrameBuffer::kGreenShift) &
- ((0x1 << GceFrameBuffer::kGreenBits) - 1);
+ return (pixel >> FBBroadcastRegionView::kGreenShift) &
+ ((0x1 << FBBroadcastRegionView::kGreenBits) - 1);
}
} // namespace
namespace cvd {
@@ -175,11 +176,7 @@
VncClientConnection::VncClientConnection(ClientSocket client,
VirtualInputs* virtual_inputs,
BlackBoard* bb, bool aggressive)
- : client_{std::move(client)},
- sensor_event_hal_{cvd::SharedFD::SocketSeqPacketClient(
- gce_sensors_message::kSensorsHALSocketName)},
- virtual_inputs_{virtual_inputs},
- bb_{bb} {
+ : client_{std::move(client)}, virtual_inputs_{virtual_inputs}, bb_{bb} {
frame_buffer_request_handler_tid_ = std::thread(
&VncClientConnection::FrameBufferUpdateRequestHandler, this, aggressive);
}
@@ -316,7 +313,7 @@
void VncClientConnection::AppendRawStripe(Message* frame_buffer_update,
const Stripe& stripe) const {
- using Pixel = GceFrameBuffer::Pixel;
+ using Pixel = FBBroadcastRegionView::Pixel;
auto& fbu = *frame_buffer_update;
AppendRawStripeHeader(&fbu, stripe);
auto init_size = fbu.size();
@@ -515,41 +512,7 @@
void VncClientConnection::UpdateAccelerometer(float /*x*/, float /*y*/,
float /*z*/) {
- // // Discard the event if we don't have a connection to the HAL.
- // if (!sensor_event_hal_->IsOpen()) {
- // LOG(ERROR) << "sensor event client not open";
- // return;
- // }
- // timespec current_time{};
- // clock_gettime(CLOCK_MONOTONIC, ¤t_time);
- // // Construct the sensor message.
- // gce_sensors_message message{};
- // message.version = sizeof message;
- // message.sensor = cvd::sensors_constants::kAccelerometerHandle;
- // message.type = SENSOR_TYPE_ACCELEROMETER;
- // message.timestamp = current_time.tv_sec * static_cast<int64_t>(1000000000)
- // +
- // current_time.tv_nsec;
- // message.data[0] = x;
- // message.data[1] = y;
- // message.data[2] = z;
-
- // std::array<iovec, 1> msg_iov{};
- // msg_iov[0].iov_base = &message;
- // msg_iov[0].iov_len = sizeof(sensors_event_t);
-
- // msghdr msg;
- // msg.msg_name = nullptr;
- // msg.msg_namelen = 0;
- // msg.msg_iov = msg_iov.data();
- // msg.msg_iovlen = msg_iov.size();
- // msg.msg_control = nullptr;
- // msg.msg_controllen = 0;
- // msg.msg_flags = 0;
- // if (sensor_event_hal_->SendMsg(&msg, 0) == -1) {
- // LOG(ERROR) << __FUNCTION__ << ": Could not send sensor data. (%s)." <<
- // sensor_event_hal_->StrError();
- // }
+ // TODO(jemoreira): Implement when vsoc sensor hal is updated
}
VncClientConnection::Coordinates VncClientConnection::CoordinatesForOrientation(
diff --git a/host/frontend/vnc_server/vnc_client_connection.h b/host/frontend/vnc_server/vnc_client_connection.h
index 71beddf..80aaad1 100644
--- a/host/frontend/vnc_server/vnc_client_connection.h
+++ b/host/frontend/vnc_server/vnc_client_connection.h
@@ -137,7 +137,6 @@
mutable std::mutex m_;
ClientSocket client_;
- cvd::SharedFD sensor_event_hal_;
bool control_key_down_ = false;
bool meta_key_down_ = false;
VirtualInputs* virtual_inputs_{};
diff --git a/host/frontend/vnc_server/vnc_utils.h b/host/frontend/vnc_server/vnc_utils.h
index f6bb44a..a4d97e7 100644
--- a/host/frontend/vnc_server/vnc_utils.h
+++ b/host/frontend/vnc_server/vnc_utils.h
@@ -21,8 +21,9 @@
#include <utility>
#include <vector>
-#include "common/vsoc/lib/fb_bcast_region_view.h"
#include "common/libs/tcp_socket/tcp_socket.h"
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+#include "host/libs/config/host_config.h"
namespace cvd {
namespace vnc {
@@ -61,21 +62,22 @@
ScreenOrientation orientation{};
};
-std::shared_ptr<vsoc::framebuffer::FBBroadcastRegionView>
-GetFBBroadcastRegionView();
-
-inline int BytesPerPixel() {
- return GetFBBroadcastRegionView()->bytes_per_pixel();
+inline constexpr int BytesPerPixel() {
+ return sizeof(vsoc::framebuffer::FBBroadcastRegionView::Pixel);
}
// The width of the screen regardless of orientation. Does not change.
inline int ActualScreenWidth() {
- return GetFBBroadcastRegionView()->x_res();
+ return vsoc::framebuffer::FBBroadcastRegionView::GetInstance(
+ vsoc::GetDomain().c_str())
+ ->x_res();
}
// The height of the screen regardless of orientation. Does not change.
inline int ActualScreenHeight() {
- return GetFBBroadcastRegionView()->y_res();
+ return vsoc::framebuffer::FBBroadcastRegionView::GetInstance(
+ vsoc::GetDomain().c_str())
+ ->y_res();
}
inline int ScreenSizeInBytes() {
diff --git a/host/libs/config/host_config.cpp b/host/libs/config/host_config.cpp
index 5b74c67..86c4be6 100644
--- a/host/libs/config/host_config.cpp
+++ b/host/libs/config/host_config.cpp
@@ -49,6 +49,10 @@
return stream.str();
}
+int vsoc::GetPerInstanceDefault(int base) {
+ return base + FLAGS_instance - 1;
+}
+
std::string vsoc::GetDefaultPerInstanceDir() {
return vsoc::GetPerInstanceDefault("/var/run/cvd-");
}
diff --git a/host/libs/config/host_config.h b/host/libs/config/host_config.h
index 8456270..65ef523 100644
--- a/host/libs/config/host_config.h
+++ b/host/libs/config/host_config.h
@@ -22,6 +22,7 @@
namespace vsoc {
std::string GetPerInstanceDefault(const char* prefix);
+int GetPerInstanceDefault(int base);
std::string GetDefaultPerInstanceDir();
std::string GetDefaultPerInstancePath(const std::string& basename);
std::string GetDefaultShmClientSocketPath();