Adapted the VNC server to run on host side.

Change-Id: I53004d5b21d8f4143cd0f1acb64508d685b556f6
diff --git a/BUILD b/BUILD
index 799583b..b3372b78 100644
--- a/BUILD
+++ b/BUILD
@@ -117,3 +117,50 @@
         "@gtest_repo//:gtest",
     ],
 )
+
+cc_binary(
+    name = "vnc_server",
+    srcs = [
+        "host/frontend/vnc_server/VirtualInputDevice.cpp",
+        "host/frontend/vnc_server/VirtualInputDevice.h",
+        "host/frontend/vnc_server/blackboard.cpp",
+        "host/frontend/vnc_server/blackboard.h",
+        "host/frontend/vnc_server/frame_buffer_watcher.cpp",
+        "host/frontend/vnc_server/frame_buffer_watcher.h",
+        "host/frontend/vnc_server/jpeg_compressor.cpp",
+        "host/frontend/vnc_server/jpeg_compressor.h",
+        "host/frontend/vnc_server/keysyms.h",
+        "host/frontend/vnc_server/main.cpp",
+        "host/frontend/vnc_server/mocks.h",
+        "host/frontend/vnc_server/simulated_hw_composer.cpp",
+        "host/frontend/vnc_server/simulated_hw_composer.h",
+        "host/frontend/vnc_server/tcp_socket.cpp",
+        "host/frontend/vnc_server/tcp_socket.h",
+        "host/frontend/vnc_server/virtual_inputs.cpp",
+        "host/frontend/vnc_server/virtual_inputs.h",
+        "host/frontend/vnc_server/vnc_client_connection.cpp",
+        "host/frontend/vnc_server/vnc_client_connection.h",
+        "host/frontend/vnc_server/vnc_server.cpp",
+        "host/frontend/vnc_server/vnc_server.h",
+        "host/frontend/vnc_server/vnc_utils.h",
+    ],
+    copts = [
+        "-Wall",
+        "-Werror",
+        "-Wno-error-unused",
+        "-Wno-error=unused-parameter",
+        "-Wno-attributes",
+    ],
+    linkopts = ["-ljpeg"],
+    deps = [
+        ":libvsoc_framebuffer",
+        ":libvsoc_gralloc",
+        ":vsoc_lib",
+        "//common/libs/fs",
+        "//common/libs/thread_safe_queue",
+        "//common/libs/threads",
+        "//common/vsoc/shm",
+        "@cuttlefish_kernel//:uapi",
+        "@glog_repo//:glog",
+    ],
+)
diff --git a/host/frontend/vnc_server/README.md b/host/frontend/vnc_server/README.md
new file mode 100644
index 0000000..52b78d1
--- /dev/null
+++ b/host/frontend/vnc_server/README.md
@@ -0,0 +1,40 @@
+# Host side VNC server
+
+## Build instructions
+
+```shell
+bazel build //host/vnc_server/:vnc_server
+```
+
+### Requirements
+
+* libjpeg-turbo8-dev
+
+## Run Instructions
+
+The vnc server receives frame updates from the hwcomposer through the shared
+memory, for which it needs to connect to the ivserver. To send input to the
+instance it temporarily connects to monkey, which is set up to run on the
+instance as a service and listens on port 6445, so you need to forward that port
+to a local socket.
+
+* Make sure to wait for monkey to start (about 16s), it's one of the last
+services to start since it's started by the zygote:
+
+```shell
+adb shell ps -e | grep monkey
+```
+
+* Forward the port to a local socket:
+
+```shell
+adb forward localfilesystem:/tmp/android-cuttlefish-1-input tcp:6445
+```
+
+* Run the server:
+
+```shell
+bazel-bin/host/vnc_server/vnc_server --port=6444 --input_socket=/tmp/android-cuttlefish-1-input
+```
+
+The VNC server will then be listening for connections on port 6444 on the host.
diff --git a/host/frontend/vnc_server/VirtualInputDevice.cpp b/host/frontend/vnc_server/VirtualInputDevice.cpp
index badeb07..038ee79 100644
--- a/host/frontend/vnc_server/VirtualInputDevice.cpp
+++ b/host/frontend/vnc_server/VirtualInputDevice.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "RemoterVirtualInput"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <linux/input.h>
@@ -25,404 +27,258 @@
 #include <sys/types.h>
 #include <vector>
 
+#include <glog/logging.h>
+#include "VirtualInputDevice.h"
 #include "keysyms.h"
 
-#define LOG_TAG "RemoterVirtualInput"
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include "VirtualInputDevice.h"
-
-#define ARRAY_SIZE(a)           \
-  ((sizeof(a) / sizeof(*(a))) / \
-   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+namespace avd {
 
 //////////////////////////
 // VirtualButton Support
 //////////////////////////
 
-namespace avd {
-uint32_t VirtualButton::Senabled_events_[] = {EV_KEY};
-
-VirtualButton::VirtualButton(const char* name, uint32_t input_keycode)
-    : VirtualInputDevice(name, BUS_USB, 0x6006, 0x6007, 1),
-      input_keycode_(input_keycode) {
-  if (!VirtualInputDevice::Init(Senabled_events_, ARRAY_SIZE(Senabled_events_),
-                                &input_keycode_, 1, NULL, 0, NULL, 0)) {
-    LOG_FATAL("VirtualInputDevice Init() failed");
-  }
-}
-
 void VirtualButton::HandleButtonPressEvent(bool button_down) {
-  EmitEvent(EV_KEY, input_keycode_, button_down);
-  EmitEvent(EV_SYN, 0, 0);
+  SendCommand(std::string("key ") + "down " + input_keycode_ + "\n");
 }
 
 //////////////////////////
 // VirtualKeyboard Support
 //////////////////////////
 
-uint32_t VirtualKeyboard::Senabled_events_[] = {EV_KEY};
-
 struct KeyEventToInput {
   uint32_t xk;
-  uint32_t input_code;
+  std::string input_code;
 };
 
 static const KeyEventToInput key_table[] = {
-    {xk::AltLeft, KEY_LEFTALT},
-    {xk::ControlLeft, KEY_LEFTCTRL},
-    {xk::ShiftLeft, KEY_LEFTSHIFT},
-    {xk::AltRight, KEY_RIGHTALT},
-    {xk::ControlRight, KEY_RIGHTCTRL},
-    {xk::ShiftRight, KEY_RIGHTSHIFT},
-    {xk::MetaLeft, KEY_LEFTMETA},
-    {xk::MetaRight, KEY_RIGHTMETA},
-    {xk::MultiKey, KEY_COMPOSE},
+    {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, KEY_CAPSLOCK},
-    {xk::NumLock, KEY_NUMLOCK},
-    {xk::ScrollLock, KEY_SCROLLLOCK},
+    {xk::CapsLock, "KEYCODE_CAPS_LOCK"},
+    {xk::NumLock, "KEYCODE_NUM_LOCK"},
+    {xk::ScrollLock, "KEYCODE_SCROLL_LOCK"},
 
-    {xk::BackSpace, KEY_BACKSPACE},
-    {xk::Tab, KEY_TAB},
-    {xk::Return, KEY_ENTER},
-    {xk::Escape, KEY_ESC},
+    {xk::BackSpace, "KEYCODE_DEL"},
+    {xk::Tab, "KEYCODE_TAB"},
+    {xk::Return, "KEYCODE_ENTER"},
+    {xk::Escape, "KEYCODE_ESCAPE"},
 
-    {' ', KEY_SPACE},
-    {'!', KEY_1},
-    {'"', KEY_APOSTROPHE},
-    {'#', KEY_3},
-    {'$', KEY_4},
-    {'%', KEY_5},
-    {'^', KEY_6},
-    {'&', KEY_7},
-    {'\'', KEY_APOSTROPHE},
-    {'(', KEY_9},
-    {')', KEY_0},
-    {'*', KEY_8},
-    {'+', KEY_EQUAL},
-    {',', KEY_COMMA},
-    {'-', KEY_MINUS},
-    {'.', KEY_DOT},
-    {'/', KEY_SLASH},
-    {'0', KEY_0},
-    {'1', KEY_1},
-    {'2', KEY_2},
-    {'3', KEY_3},
-    {'4', KEY_4},
-    {'5', KEY_5},
-    {'6', KEY_6},
-    {'7', KEY_7},
-    {'8', KEY_8},
-    {'9', KEY_9},
-    {':', KEY_SEMICOLON},
-    {';', KEY_SEMICOLON},
-    {'<', KEY_COMMA},
-    {'=', KEY_EQUAL},
-    {'>', KEY_DOT},
-    {'?', KEY_SLASH},
-    {'@', KEY_2},
-    {'A', KEY_A},
-    {'B', KEY_B},
-    {'C', KEY_C},
-    {'D', KEY_D},
-    {'E', KEY_E},
-    {'F', KEY_F},
-    {'G', KEY_G},
-    {'H', KEY_H},
-    {'I', KEY_I},
-    {'J', KEY_J},
-    {'K', KEY_K},
-    {'L', KEY_L},
-    {'M', KEY_M},
-    {'N', KEY_N},
-    {'O', KEY_O},
-    {'P', KEY_P},
-    {'Q', KEY_Q},
-    {'R', KEY_R},
-    {'S', KEY_S},
-    {'T', KEY_T},
-    {'U', KEY_U},
-    {'V', KEY_V},
-    {'W', KEY_W},
-    {'X', KEY_X},
-    {'Y', KEY_Y},
-    {'Z', KEY_Z},
-    {'[', KEY_LEFTBRACE},
-    {'\\', KEY_BACKSLASH},
-    {']', KEY_RIGHTBRACE},
-    {'-', KEY_MINUS},
-    {'_', KEY_MINUS},
-    {'`', KEY_GRAVE},
-    {'a', KEY_A},
-    {'b', KEY_B},
-    {'c', KEY_C},
-    {'d', KEY_D},
-    {'e', KEY_E},
-    {'f', KEY_F},
-    {'g', KEY_G},
-    {'h', KEY_H},
-    {'i', KEY_I},
-    {'j', KEY_J},
-    {'k', KEY_K},
-    {'l', KEY_L},
-    {'m', KEY_M},
-    {'n', KEY_N},
-    {'o', KEY_O},
-    {'p', KEY_P},
-    {'q', KEY_Q},
-    {'r', KEY_R},
-    {'s', KEY_S},
-    {'t', KEY_T},
-    {'u', KEY_U},
-    {'v', KEY_V},
-    {'w', KEY_W},
-    {'x', KEY_X},
-    {'y', KEY_Y},
-    {'z', KEY_Z},
-    {'{', KEY_LEFTBRACE},
-    {'\\', KEY_BACKSLASH},
-    {'|', KEY_BACKSLASH},
-    {'}', KEY_RIGHTBRACE},
-    {'~', KEY_GRAVE},
+    {' ', "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, KEY_F1},
-    {xk::F2, KEY_F2},
-    {xk::F3, KEY_F3},
-    {xk::F4, KEY_F4},
-    {xk::F5, KEY_F5},
-    {xk::F6, KEY_F6},
-    {xk::F7, KEY_F7},
-    {xk::F8, KEY_F8},
-    {xk::F9, KEY_F9},
-    {xk::F10, KEY_F10},
-    {xk::F11, KEY_F11},
-    {xk::F12, KEY_F12},
-    {xk::F13, KEY_F13},
-    {xk::F14, KEY_F14},
-    {xk::F15, KEY_F15},
-    {xk::F16, KEY_F16},
-    {xk::F17, KEY_F17},
-    {xk::F18, KEY_F18},
-    {xk::F19, KEY_F19},
-    {xk::F20, KEY_F20},
-    {xk::F21, KEY_F21},
-    {xk::F22, KEY_F22},
-    {xk::F23, KEY_F23},
-    {xk::F24, KEY_F24},
+    {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, KEY_KP0},
-    {xk::Keypad1, KEY_KP1},
-    {xk::Keypad2, KEY_KP2},
-    {xk::Keypad3, KEY_KP3},
-    {xk::Keypad4, KEY_KP4},
-    {xk::Keypad5, KEY_KP5},
-    {xk::Keypad6, KEY_KP6},
-    {xk::Keypad7, KEY_KP7},
-    {xk::Keypad8, KEY_KP8},
-    {xk::Keypad9, KEY_KP9},
-    {xk::KeypadMultiply, KEY_KPASTERISK},
-    {xk::KeypadSubtract, KEY_KPMINUS},
-    {xk::KeypadAdd, KEY_KPPLUS},
-    {xk::KeypadDecimal, KEY_KPDOT},
-    {xk::KeypadEnter, KEY_KPENTER},
-    {xk::KeypadDivide, KEY_KPSLASH},
-    {xk::KeypadEqual, KEY_KPEQUAL},
-    {xk::PlusMinus, KEY_KPPLUSMINUS},
+    {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, KEY_SYSRQ},
-    {xk::LineFeed, KEY_LINEFEED},
-    {xk::Home, KEY_HOME},
-    {xk::Up, KEY_UP},
-    {xk::PageUp, KEY_PAGEUP},
-    {xk::Left, KEY_LEFT},
-    {xk::Right, KEY_RIGHT},
-    {xk::End, KEY_END},
-    {xk::Down, KEY_DOWN},
-    {xk::PageDown, KEY_PAGEDOWN},
-    {xk::Insert, KEY_INSERT},
-    {xk::Delete, KEY_DELETE},
-    {xk::Pause, KEY_PAUSE},
-    {xk::KeypadSeparator, KEY_KPCOMMA},
-    {xk::Yen, KEY_YEN},
-    {xk::Cancel, KEY_STOP},
-    {xk::Redo, KEY_AGAIN},
-    {xk::Undo, KEY_UNDO},
-    {xk::Find, KEY_FIND},
-    {xk::Print, KEY_PRINT},
-    {xk::VolumeDown, KEY_VOLUMEDOWN},
-    {xk::Mute, KEY_MUTE},
-    {xk::VolumeUp, KEY_VOLUMEUP},
-    {xk::Menu, KEY_MENU},
-    {xk::VNCMenu, KEY_MENU},
+    {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(const char* name)
-    : VirtualInputDevice(name, BUS_USB, 0x6006, 0x6008, 1) {
-  std::vector<uint32_t> keycodes(ARRAY_SIZE(key_table));
-  for (size_t i = 0; i < keycodes.size(); ++i) {
-    keymapping_[key_table[i].xk] = key_table[i].input_code;
-    keycodes[i] = key_table[i].input_code;
-  }
-
-  if (!VirtualInputDevice::Init(Senabled_events_, ARRAY_SIZE(Senabled_events_),
-                                &keycodes[0], keycodes.size(), NULL, 0, NULL,
-                                0)) {
-    LOG_FATAL("VirtualInputDevice Init() failed");
+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)) {
-    EmitEvent(EV_KEY, keymapping_[keycode], button_down);
-    EmitEvent(EV_SYN, 0, 0);
+    SendCommand(std::string("key ") + (button_down ? "down " : "up ") +
+                keymapping_[keycode] + "\n");
+  } else {
+    LOG(INFO) << "Unknown keycode " << keycode;
   }
-  ALOGI("Unknown keycode %d", keycode);
 }
 
 //////////////////////////
 // VirtualTouchPad Support
 //////////////////////////
 
-uint32_t VirtualTouchPad::Senabled_events_[] = {EV_ABS, EV_KEY, EV_SYN};
-uint32_t VirtualTouchPad::Senabled_keys_[] = {BTN_TOUCH};
-uint32_t VirtualTouchPad::Senabled_abs_[] = {ABS_X, ABS_Y};
-uint32_t VirtualTouchPad::Senabled_props_[] = {INPUT_PROP_DIRECT};
-
-VirtualTouchPad::VirtualTouchPad(const char* name, int x_res, int y_res)
-    : VirtualInputDevice(name, BUS_USB, 0x6006, 0x6006, 1),
-      x_res_(x_res),
-      y_res_(y_res) {
-  // Customization of uinput_user_dev() must happen before calling our base
-  // Init().
-  uinput_user_dev()->absmin[ABS_X] = 0;
-  uinput_user_dev()->absmax[ABS_X] = x_res_;
-  uinput_user_dev()->absmin[ABS_Y] = 0;
-  uinput_user_dev()->absmax[ABS_Y] = y_res_;
-
-  if (!VirtualInputDevice::Init(Senabled_events_, ARRAY_SIZE(Senabled_events_),
-                                Senabled_keys_, ARRAY_SIZE(Senabled_keys_),
-                                Senabled_abs_, ARRAY_SIZE(Senabled_abs_),
-                                Senabled_props_, ARRAY_SIZE(Senabled_props_))) {
-    LOG_FATAL("VirtualInputDevice Init() failed");
+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) {
-  EmitEvent(EV_ABS, ABS_X, x);
-  EmitEvent(EV_ABS, ABS_Y, y);
-  EmitEvent(EV_KEY, BTN_TOUCH, touch_down);
-  EmitEvent(EV_SYN, 0, 0);
-}
-
-//////////////////////////////////
-// Base VirtualInputDevice Support
-//////////////////////////////////
-VirtualInputDevice::VirtualInputDevice(const char* name, uint16_t bus_type,
-                                       uint16_t vendor, uint16_t product,
-                                       uint16_t version)
-    : fd_(-1) {
-  memset(&uinput_user_dev_, 0, sizeof(uinput_user_dev_));
-  strncpy(uinput_user_dev_.name, name, sizeof(uinput_user_dev_.name));
-  uinput_user_dev_.id.bustype = bus_type;
-  uinput_user_dev_.id.vendor = vendor;
-  uinput_user_dev_.id.product = product;
-  uinput_user_dev_.id.version = version;
-}
-
-VirtualInputDevice::~VirtualInputDevice() {
-  if (fd_ != -1) {
-    close(fd_);
-    fd_ = -1;
-  }
-}
-
-bool VirtualInputDevice::Init(uint32_t* events, int num_events, uint32_t* keys,
-                              int num_keys, uint32_t* abs, int num_abs,
-                              uint32_t* props, int num_props) {
-  if ((fd_ = open("/dev/uinput", O_WRONLY | O_NONBLOCK)) < 0) {
-    SLOGE("Failed to open /dev/uinput (%s)", strerror(errno));
-    return false;
-  }
-  if (events && !EnableEventBits(events, num_events)) {
-    SLOGE("Failed to set event bits (%s)", strerror(errno));
-    return false;
-  }
-  if (keys && !EnableKeyBits(keys, num_keys)) {
-    SLOGE("Failed to set key bits (%s)", strerror(errno));
-    return false;
-  }
-  if (abs && !EnableAbsBits(abs, num_abs)) {
-    SLOGE("Failed to set abs bits (%s)", strerror(errno));
-    return false;
-  }
-  if (props && !EnablePropBits(props, num_props)) {
-    SLOGE("Failed to set prop bits (%s)", strerror(errno));
-    return false;
-  }
-  if (!FinalizeDeviceCreation()) {
-    SLOGE("Failed to finalize device creation (%s)", strerror(errno));
-    return false;
-  }
-  return true;
-}
-
-bool VirtualInputDevice::EmitEvent(uint16_t type, uint16_t code,
-                                   uint32_t value) {
-  struct input_event ev;
-  ev.type = type;
-  ev.code = code;
-  ev.value = value;
-  if (write(fd_, &ev, sizeof(ev)) < 0) {
-    SLOGE("write() failed (%s)", strerror(errno));
-    return false;
-  }
-  return true;
-}
-
-bool VirtualInputDevice::DoIoctls(int request, uint32_t* list,
-                                  int num_elements) {
-  for (int i = 0; i < num_elements; i++) {
-    int rc = ioctl(fd_, request, *list++);
-    if (rc < 0) {
-      SLOGE("ioctl failed (%s)", strerror(errno));
-      return false;
-    }
-  }
-  return true;
-}
-
-bool VirtualInputDevice::EnableEventBits(uint32_t* events, int num_elements) {
-  return DoIoctls(UI_SET_EVBIT, events, num_elements);
-}
-
-bool VirtualInputDevice::EnableKeyBits(uint32_t* keys, int num_elements) {
-  return DoIoctls(UI_SET_KEYBIT, keys, num_elements);
-}
-
-bool VirtualInputDevice::EnableAbsBits(uint32_t* abs, int num_elements) {
-  return DoIoctls(UI_SET_ABSBIT, abs, num_elements);
-}
-
-bool VirtualInputDevice::EnablePropBits(uint32_t* props, int num_elements) {
-// JB and ICE do not have the latest uinput headers.
-#ifndef UI_SET_PROPBIT
-#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
-#endif  // #ifndef UI_SET_PROPBIT
-  return DoIoctls(UI_SET_PROPBIT, props, num_elements);
-}
-
-bool VirtualInputDevice::FinalizeDeviceCreation() {
-  if (write(fd_, &uinput_user_dev_, sizeof(uinput_user_dev_)) < 0) {
-    SLOGE("Unable to set input device info (%s)", strerror(errno));
-    return false;
-  }
-  if (ioctl(fd_, UI_DEV_CREATE) < 0) {
-    SLOGE("Unable to create input device (%s)", strerror(errno));
-    return false;
-  }
-  return true;
+  SendCommand(GetCommand(touch_down, x, y) + std::to_string(x) + " " +
+              std::to_string(y) + "\n");
 }
 
 }  // namespace avd
diff --git a/host/frontend/vnc_server/VirtualInputDevice.h b/host/frontend/vnc_server/VirtualInputDevice.h
index 2d1b928..1b9506e 100644
--- a/host/frontend/vnc_server/VirtualInputDevice.h
+++ b/host/frontend/vnc_server/VirtualInputDevice.h
@@ -17,81 +17,63 @@
 #ifndef VIRTUAL_INPUT_DEVICE_H_
 #define VIRTUAL_INPUT_DEVICE_H_
 
-#include <linux/uinput.h>
+#include <functional>
 #include <map>
+#include <string>
 
 namespace avd {
+
 // Base virtual input device class which contains a bunch of boiler-plate code.
 class VirtualInputDevice {
  public:
-  VirtualInputDevice(const char* name, uint16_t bus_type, uint16_t vendor,
-                     uint16_t product, uint16_t version);
-  virtual ~VirtualInputDevice();
+  VirtualInputDevice(std::function<bool(std::string)> cmd_sender)
+      : send_command_(cmd_sender) {}
 
  protected:
-  bool Init(uint32_t* events, int num_events, uint32_t* keys, int num_keys,
-            uint32_t* abs, int num_abs, uint32_t* props, int num_props);
-
-  bool EmitEvent(uint16_t type, uint16_t code, uint32_t value);
-
-  struct uinput_user_dev* uinput_user_dev() {
-    return &uinput_user_dev_;
-  }
+  bool SendCommand(std::string cmd) { return send_command_(cmd); }
 
  private:
-  bool EnableEventBits(uint32_t* events, int num_elements);
-  bool EnableKeyBits(uint32_t* keys, int num_elements);
-  bool EnableAbsBits(uint32_t* abs, int num_elements);
-  bool EnablePropBits(uint32_t* props, int num_elements);
-  bool DoIoctls(int request, uint32_t* list, int num_elements);
-  bool FinalizeDeviceCreation();
-
-  int fd_;
-  struct uinput_user_dev uinput_user_dev_;
+  std::function<bool(std::string)> send_command_;
 };
 
 // Virtual touch-pad.
 class VirtualTouchPad : public VirtualInputDevice {
  public:
-  VirtualTouchPad(const char* name, int x_res, int y_res);
-  virtual ~VirtualTouchPad() {}
+  VirtualTouchPad(std::function<bool(std::string)> cmd_sender)
+      : VirtualInputDevice(cmd_sender) {}
 
   void HandlePointerEvent(bool touch_down, int x, int y);
 
  private:
-  static uint32_t Senabled_events_[];
-  static uint32_t Senabled_keys_[];
-  static uint32_t Senabled_abs_[];
-  static uint32_t Senabled_props_[];
-
-  int x_res_;
-  int y_res_;
+  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(const char* name, uint32_t input_keycode);
-  virtual ~VirtualButton() {}
+  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:
-  static uint32_t Senabled_events_[];
-  uint32_t input_keycode_;
+  std::string input_keycode_;
 };
 
 // Virtual keyboard.
 class VirtualKeyboard : public VirtualInputDevice {
  public:
-  VirtualKeyboard(const char* name);
+  VirtualKeyboard(std::function<bool(std::string)> cmd_sender);
   virtual ~VirtualKeyboard() {}
 
   void GenerateKeyPressEvent(int code, bool down);
 
  private:
-  static uint32_t Senabled_events_[];
-  std::map<uint32_t, uint32_t> keymapping_;
+  std::map<uint32_t, std::string> keymapping_;
 };
 
 }  // namespace avd
diff --git a/host/frontend/vnc_server/blackboard.cpp b/host/frontend/vnc_server/blackboard.cpp
index 5f1a92c..1c32b59 100644
--- a/host/frontend/vnc_server/blackboard.cpp
+++ b/host/frontend/vnc_server/blackboard.cpp
@@ -4,7 +4,7 @@
 #include "frame_buffer_watcher.h"
 
 #define LOG_TAG "GceVNCServer"
-#include <cutils/log.h>
+#include <glog/logging.h>
 
 using avd::vnc::BlackBoard;
 using avd::vnc::Stripe;
@@ -15,7 +15,7 @@
 
 void BlackBoard::NewStripeReady(int index, StripeSeqNumber seq_num) {
   std::lock_guard<std::mutex> guard(m_);
-  D("new stripe arrived from frame watcher");
+  DLOG(INFO) << "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_) {
@@ -28,7 +28,7 @@
 void BlackBoard::Register(const VncClientConnection* conn) {
   {
     std::lock_guard<std::mutex> guard(m_);
-    ALOG_ASSERT(!clients_.count(conn));
+    CHECK(!clients_.count(conn));
     clients_[conn];  // constructs new state in place
   }
   new_client_cv_.notify_one();
@@ -36,12 +36,12 @@
 
 void BlackBoard::Unregister(const VncClientConnection* conn) {
   std::lock_guard<std::mutex> guard(m_);
-  ALOG_ASSERT(clients_.count(conn));
+  CHECK(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());
+  CHECK(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) {
@@ -56,12 +56,12 @@
     const VncClientConnection* conn) {
   std::unique_lock<std::mutex> guard(m_);
   auto& state = GetStateForClient(conn);
-  D("Waiting for stripe...");
+  DLOG(INFO) << "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);
+  DLOG(INFO) << "At least one new stripe is available, should unblock " << conn;
   state.ready_to_receive = false;
   auto new_stripes = frame_buffer_watcher_->StripesNewerThan(
       state.orientation, state.stripe_seq_nums);
@@ -101,7 +101,7 @@
 void BlackBoard::FrameBufferUpdateRequestReceived(
     const VncClientConnection* conn) {
   std::lock_guard<std::mutex> guard(m_);
-  D("Received frame buffer update request");
+  DLOG(INFO) << "Received frame buffer update request";
   auto& state = GetStateForClient(conn);
   state.ready_to_receive = true;
   state.new_frame_cv.notify_one();
@@ -128,16 +128,17 @@
   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);
+    LOG(WARNING) << "Bogus jpeg quality level: " << quality_level
+                 << ". Quality must be in range [" << kJpegMinQualityEncoding
+                 << ", " << kJpegMaxQualityEncoding << "]";
     return;
   }
   jpeg_quality_level_ = 55 + (5 * (quality_level + 32));
-  D("jpeg quality level set to %d%%:", jpeg_quality_level_);
+  DLOG(INFO) << "jpeg quality level set to " << jpeg_quality_level_ << "%";
 }
 
 BlackBoard::ClientFBUState& BlackBoard::GetStateForClient(
     const VncClientConnection* conn) {
-  ALOG_ASSERT(clients_.count(conn));
+  CHECK(clients_.count(conn));
   return clients_[conn];
 }
diff --git a/host/frontend/vnc_server/blackboard.h b/host/frontend/vnc_server/blackboard.h
index 15b0cb9..30eff20 100644
--- a/host/frontend/vnc_server/blackboard.h
+++ b/host/frontend/vnc_server/blackboard.h
@@ -1,10 +1,9 @@
 #ifndef DEVICE_GOOGLE_GCE_GCE_UTILS_GCE_VNC_SERVER_BLACKBOARD_H_
 #define DEVICE_GOOGLE_GCE_GCE_UTILS_GCE_VNC_SERVER_BLACKBOARD_H_
 
+#include "common/libs/threads/thread_annotations.h"
 #include "vnc_utils.h"
 
-#include <android-base/thread_annotations.h>
-
 #include <condition_variable>
 #include <memory>
 #include <mutex>
diff --git a/host/frontend/vnc_server/frame_buffer_watcher.cpp b/host/frontend/vnc_server/frame_buffer_watcher.cpp
index b8e66b2..74495a2 100644
--- a/host/frontend/vnc_server/frame_buffer_watcher.cpp
+++ b/host/frontend/vnc_server/frame_buffer_watcher.cpp
@@ -1,5 +1,4 @@
 #include "frame_buffer_watcher.h"
-#include <ThreadSafeQueue.hpp>
 #include "vnc_utils.h"
 
 #include <algorithm>
@@ -12,7 +11,7 @@
 #include <utility>
 
 #define LOG_TAG "GceVNCServer"
-#include <cutils/log.h>
+#include <glog/logging.h>
 
 using avd::vnc::FrameBufferWatcher;
 
@@ -46,8 +45,9 @@
 }
 
 avd::vnc::Stripe FrameBufferWatcher::Rotated(Stripe stripe) {
-  LOG_ALWAYS_FATAL_IF(stripe.orientation == ScreenOrientation::Landscape,
-                      "Rotating a landscape stripe, this is a mistake");
+  if (stripe.orientation == ScreenOrientation::Landscape) {
+    LOG(FATAL) << "Rotating a landscape stripe, this is a mistake";
+  }
   auto w = stripe.width;
   auto h = stripe.height;
   const auto& raw = stripe.raw_data;
@@ -56,8 +56,8 @@
     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());
+      CHECK(from < raw.size());
+      CHECK(to < rotated.size());
       std::memcpy(&rotated[to], &raw[from], BytesPerPixel());
     }
   }
@@ -77,7 +77,7 @@
     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());
+  CHECK(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),
diff --git a/host/frontend/vnc_server/frame_buffer_watcher.h b/host/frontend/vnc_server/frame_buffer_watcher.h
index 9c23f7e..ca11613 100644
--- a/host/frontend/vnc_server/frame_buffer_watcher.h
+++ b/host/frontend/vnc_server/frame_buffer_watcher.h
@@ -2,6 +2,7 @@
 #define DEVICE_GOOGLE_GCE_GCE_UTILS_GCE_VNC_SERVER_FRAME_BUFFER_WATCHER_H_
 
 #include "blackboard.h"
+#include "common/libs/threads/thread_annotations.h"
 #include "jpeg_compressor.h"
 #include "simulated_hw_composer.h"
 
diff --git a/host/frontend/vnc_server/jpeg_compressor.cpp b/host/frontend/vnc_server/jpeg_compressor.cpp
index c897380..6a0f735 100644
--- a/host/frontend/vnc_server/jpeg_compressor.cpp
+++ b/host/frontend/vnc_server/jpeg_compressor.cpp
@@ -5,7 +5,7 @@
 #include <stdio.h>  // stdio.h must appear before jpeglib.h
 
 #define LOG_TAG "GceVNCServer"
-#include <cutils/log.h>
+#include <glog/logging.h>
 
 using avd::vnc::JpegCompressor;
 
@@ -55,11 +55,8 @@
 
 void JpegCompressor::UpdateBuffer(std::uint8_t* compression_buffer,
                                   unsigned long compression_buffer_size) {
-  if (buffer_capacity_ < compression_buffer_size) {
-    ALOG_ASSERT(buffer_ != compression_buffer);
+  if (buffer_.get() != compression_buffer) {
     buffer_capacity_ = compression_buffer_size;
     buffer_.reset(compression_buffer);
-  } else {
-    ALOG_ASSERT(buffer_ == compression_buffer);
   }
 }
diff --git a/host/frontend/vnc_server/keysyms.h b/host/frontend/vnc_server/keysyms.h
index 29e5c8d..06f3c14 100644
--- a/host/frontend/vnc_server/keysyms.h
+++ b/host/frontend/vnc_server/keysyms.h
@@ -1,6 +1,8 @@
 #ifndef DEVICE_GOOGLE_GCE_KEYSYMS_H_
 #define DEVICE_GOOGLE_GCE_KEYSYMS_H_
 
+#include <cstdint>
+
 namespace avd {
 namespace xk {
 
diff --git a/host/frontend/vnc_server/main.cpp b/host/frontend/vnc_server/main.cpp
index 4b06cb0..5808a2b 100644
--- a/host/frontend/vnc_server/main.cpp
+++ b/host/frontend/vnc_server/main.cpp
@@ -3,18 +3,13 @@
 #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
+DEFINE_bool(agressive, false, "Whether to use agressive server");
+DEFINE_int32(port, 6444, "Port where to listen for connections");
 
 int main(int argc, char* argv[]) {
-  avd::vnc::VncServer vnc_server(kVncServerPort, HasAggressiveFlag(argc, argv));
+  google::InitGoogleLogging(argv[0]);
+  google::InstallFailureSignalHandler();
+  google::ParseCommandLineFlags(&argc, &argv, true);
+  avd::vnc::VncServer vnc_server(FLAGS_port, FLAGS_agressive);
   vnc_server.MainLoop();
 }
diff --git a/host/frontend/vnc_server/mocks.h b/host/frontend/vnc_server/mocks.h
new file mode 100644
index 0000000..315fc9d
--- /dev/null
+++ b/host/frontend/vnc_server/mocks.h
@@ -0,0 +1,17 @@
+struct GceFrameBuffer {
+  typedef uint32_t Pixel;
+
+  static const int kRedShift = 0;
+  static const int kRedBits = 8;
+  static const int kGreenShift = 8;
+  static const int kGreenBits = 8;
+  static const int kBlueShift = 16;
+  static const int kBlueBits = 8;
+  static const int kAlphaShift = 24;
+  static const int kAlphaBits = 8;
+};
+
+// Sensors
+struct gce_sensors_message {
+  static constexpr const char* const kSensorsHALSocketName = "";
+};
diff --git a/host/frontend/vnc_server/simulated_hw_composer.cpp b/host/frontend/vnc_server/simulated_hw_composer.cpp
index b4f80ce..f6901ab 100644
--- a/host/frontend/vnc_server/simulated_hw_composer.cpp
+++ b/host/frontend/vnc_server/simulated_hw_composer.cpp
@@ -1,26 +1,26 @@
 #include "simulated_hw_composer.h"
 
+#include "common/vsoc/lib/typed_region_view.h"
+#include "host/vsoc/gralloc/gralloc_buffer_region.h"
+#include "vnc_utils.h"
+
 using avd::vnc::SimulatedHWComposer;
+using vsoc::gralloc::GrallocBufferRegion;
 
 SimulatedHWComposer::SimulatedHWComposer(BlackBoard* bb)
     :
 #ifdef FUZZ_TEST_VNC
       engine_{std::random_device{}()},
 #endif
-      control_{GceFrameBufferControl::getInstance()},
+      fb_region_{vsoc::framebuffer::FBBroadcastRegion::GetInstance()},
       bb_{bb},
       stripes_(kMaxQueueElements, &SimulatedHWComposer::EraseHalfOfElements) {
-  void* p{};
-  GceFrameBuffer::OpenAndMapFrameBuffer(&p, &frame_buffer_fd_);
-  frame_buffer_memory_ = static_cast<char*>(p);
   stripe_maker_ = std::thread(&SimulatedHWComposer::MakeStripes, this);
 }
 
 SimulatedHWComposer::~SimulatedHWComposer() {
   close();
   stripe_maker_.join();
-  GceFrameBuffer::UnmapAndCloseFrameBuffer(frame_buffer_memory_,
-                                           frame_buffer_fd_);
 }
 
 avd::vnc::Stripe SimulatedHWComposer::GetNewStripe() {
@@ -61,12 +61,11 @@
   std::uint64_t stripe_seq_num = 1;
   while (!closed()) {
     bb_->WaitForAtLeastOneClientConnection();
-    int y_offset{};
-    control_.WaitForFrameBufferChangeSince(previous_seq_num, &y_offset,
-                                           &previous_seq_num, nullptr);
+    vsoc_reg_off_t buffer_offset =
+        fb_region_->WaitForNewFrameSince(&previous_seq_num);
 
     const auto* frame_start =
-        frame_buffer_memory_ + y_offset * ActualScreenWidth() * BytesPerPixel();
+        GrallocBufferRegion::GetInstance()->OffsetToBufferPtr(buffer_offset);
     raw_screen.assign(frame_start, frame_start + ScreenSizeInBytes());
 
     for (int i = 0; i < kNumStripes; ++i) {
diff --git a/host/frontend/vnc_server/simulated_hw_composer.h b/host/frontend/vnc_server/simulated_hw_composer.h
index 3b68548..4e22676 100644
--- a/host/frontend/vnc_server/simulated_hw_composer.h
+++ b/host/frontend/vnc_server/simulated_hw_composer.h
@@ -1,11 +1,10 @@
-#ifndef DEVICE_GOOGLE_GCE_GCE_UTILS_GCE_VNC_SERVER_SIMULATED_HW_COMPOSER_H_
-#define DEVICE_GOOGLE_GCE_GCE_UTILS_GCE_VNC_SERVER_SIMULATED_HW_COMPOSER_H_
+#pragma once
 
 #include "blackboard.h"
 
-#include <GceFrameBuffer.h>
-#include <GceFrameBufferControl.h>
-#include <ThreadSafeQueue.hpp>
+#include "common/libs/thread_safe_queue/thread_safe_queue.h"
+#include "common/libs/threads/thread_annotations.h"
+#include "common/vsoc/framebuffer/fb_bcast_region.h"
 
 #include <mutex>
 #include <thread>
@@ -44,14 +43,10 @@
   constexpr static std::size_t kMaxQueueElements = 64;
   bool closed_ GUARDED_BY(m_){};
   std::mutex m_;
-  GceFrameBufferControl& control_;
+  vsoc::framebuffer::FBBroadcastRegion* fb_region_;
   BlackBoard* bb_{};
   ThreadSafeQueue<Stripe> stripes_;
   std::thread stripe_maker_;
-  char* frame_buffer_memory_{};
-  int frame_buffer_fd_{};
 };
 }  // namespace vnc
 }  // namespace avd
-
-#endif
diff --git a/host/frontend/vnc_server/tcp_socket.cpp b/host/frontend/vnc_server/tcp_socket.cpp
index b18ad15..2fe8b34 100644
--- a/host/frontend/vnc_server/tcp_socket.cpp
+++ b/host/frontend/vnc_server/tcp_socket.cpp
@@ -1,10 +1,13 @@
 #include "tcp_socket.h"
 #include <cerrno>
 
-#include <cutils/sockets.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 #define LOG_TAG "GceVNCServer"
-#include <cutils/log.h>
+#include <glog/logging.h>
 
+using avd::SharedFD;
 using avd::vnc::ClientSocket;
 using avd::vnc::Message;
 using avd::vnc::ServerSocket;
@@ -13,17 +16,17 @@
   Message buf(length);
   ssize_t total_read = 0;
   while (total_read < static_cast<ssize_t>(length)) {
-    auto just_read = read(fd_, &buf[total_read], buf.size() - total_read);
+    auto just_read = fd_->Read(&buf[total_read], buf.size() - total_read);
     if (just_read <= 0) {
       if (just_read < 0) {
-        ALOGE("read() error: %s", strerror(errno));
+        LOG(ERROR) << "read() error: " << strerror(errno);
       }
       other_side_closed_ = true;
       return Message{};
     }
     total_read += just_read;
   }
-  ALOG_ASSERT(total_read == static_cast<ssize_t>(length));
+  CHECK(total_read == static_cast<ssize_t>(length));
   return buf;
 }
 
@@ -31,9 +34,9 @@
   std::lock_guard<std::mutex> lock(send_lock_);
   ssize_t written{};
   while (written < static_cast<ssize_t>(size)) {
-    auto just_written = write(fd_, data + written, size - written);
+    auto just_written = fd_->Write(data + written, size - written);
     if (just_written <= 0) {
-      ALOGI("Couldn't write to vnc client: %s", strerror(errno));
+      LOG(INFO) << "Couldn't write to vnc client: " << strerror(errno);
       return just_written;
     }
     written += just_written;
@@ -46,16 +49,16 @@
 }
 
 ServerSocket::ServerSocket(int port)
-    : fd_{socket_inaddr_any_server(port, SOCK_STREAM)} {
-  if (fd_ < 0) {
-    LOG_FATAL("Couldn't open streaming server on port %d", port);
+    : fd_{SharedFD::SocketLocalServer(port, SOCK_STREAM)} {
+  if (!fd_->IsOpen()) {
+    LOG(FATAL) << "Couldn't open streaming server on port " << port;
   }
 }
 
 ClientSocket ServerSocket::Accept() {
-  int client = accept(fd_, nullptr, nullptr);
-  if (client < 0) {
-    LOG_FATAL("Error attemping to accept: %s", strerror(errno));
+  SharedFD client = SharedFD::Accept(*fd_);
+  if (!client->IsOpen()) {
+    LOG(FATAL) << "Error attemping to accept: " << strerror(errno);
   }
   return ClientSocket{client};
 }
diff --git a/host/frontend/vnc_server/tcp_socket.h b/host/frontend/vnc_server/tcp_socket.h
index 8cbd217..572d9cf 100644
--- a/host/frontend/vnc_server/tcp_socket.h
+++ b/host/frontend/vnc_server/tcp_socket.h
@@ -18,26 +18,16 @@
 // Send is thread safe in this regard, Recv is not.
 class ClientSocket {
  public:
-  ClientSocket(ClientSocket&& other) : fd_{other.fd_} { other.fd_ = -1; }
+  ClientSocket(ClientSocket&& other) : fd_{other.fd_} {}
 
   ClientSocket& operator=(ClientSocket&& other) {
-    if (fd_ >= 0) {
-      close(fd_);
-    }
     fd_ = other.fd_;
-    other.fd_ = -1;
     return *this;
   }
 
   ClientSocket(const ClientSocket&) = delete;
   ClientSocket& operator=(const ClientSocket&) = delete;
 
-  ~ClientSocket() {
-    if (fd_ >= 0) {
-      close(fd_);
-    }
-  }
-
   Message Recv(std::size_t length);
   ssize_t Send(const std::uint8_t* data, std::size_t size);
   ssize_t Send(const Message& message);
@@ -51,9 +41,9 @@
 
  private:
   friend ServerSocket;
-  explicit ClientSocket(int fd) : fd_(fd) {}
+  explicit ClientSocket(avd::SharedFD fd) : fd_(fd) {}
 
-  int fd_ = -1;
+  avd::SharedFD fd_;
   bool other_side_closed_{};
   std::mutex send_lock_;
 };
@@ -65,16 +55,10 @@
   ServerSocket(const ServerSocket&) = delete;
   ServerSocket& operator=(const ServerSocket&) = delete;
 
-  ~ServerSocket() {
-    if (fd_ >= 0) {
-      close(fd_);
-    }
-  }
-
   ClientSocket Accept();
 
  private:
-  int fd_ = -1;
+  avd::SharedFD fd_;
 };
 
 }  // namespace vnc
diff --git a/host/frontend/vnc_server/virtual_inputs.cpp b/host/frontend/vnc_server/virtual_inputs.cpp
index c946d57..3912f7b 100644
--- a/host/frontend/vnc_server/virtual_inputs.cpp
+++ b/host/frontend/vnc_server/virtual_inputs.cpp
@@ -1,8 +1,53 @@
 #include "virtual_inputs.h"
+#include <gflags/gflags.h>
+
 #include <mutex>
+#include <thread>
+
+DEFINE_string(input_socket, "/tmp/android-cuttlefish-1-input",
+              "The name of unix socket where the monkey server is listening "
+              "for input commands");
 
 using avd::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_ = avd::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_ = avd::SharedFD::SocketLocalClient(
+        FLAGS_input_socket.c_str(), false, SOCK_STREAM);
+    if (!monkey_socket_->IsOpen()) {
+      LOG(FATAL) << "Unable to connect to the mokey server";
+    }
+  }
+}
+
+namespace {
+constexpr char kCmdDone[] = "done\n";
+}  // anonymous namespace
+
+VirtualInputs::~VirtualInputs() {
+  if (monkey_socket_->IsOpen()) {
+    monkey_socket_->Send(kCmdDone, sizeof(kCmdDone) - 1, 0);
+  }
+}
+
+bool VirtualInputs::SendMonkeyComand(std::string cmd) {
+  return 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);
diff --git a/host/frontend/vnc_server/virtual_inputs.h b/host/frontend/vnc_server/virtual_inputs.h
index 604dc87..502dee4 100644
--- a/host/frontend/vnc_server/virtual_inputs.h
+++ b/host/frontend/vnc_server/virtual_inputs.h
@@ -4,7 +4,9 @@
 #include "VirtualInputDevice.h"
 #include "vnc_utils.h"
 
-#include <android-base/thread_annotations.h>
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/threads/thread_annotations.h"
+
 #include <linux/input.h>
 
 #include <mutex>
@@ -14,16 +16,20 @@
 
 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:
+  avd::SharedFD monkey_socket_;
+  bool SendMonkeyComand(std::string cmd);
   std::mutex m_;
-  VirtualKeyboard virtual_keyboard_ GUARDED_BY(m_){"remote-keyboard"};
-  VirtualTouchPad virtual_touch_pad_ GUARDED_BY(m_){
-      "remote-touchpad", ActualScreenWidth(), ActualScreenHeight()};
-  VirtualButton virtual_power_button_ GUARDED_BY(m_){"remote-power", KEY_POWER};
+  VirtualKeyboard virtual_keyboard_ GUARDED_BY(m_);
+  VirtualTouchPad virtual_touch_pad_ GUARDED_BY(m_);
+  VirtualButton virtual_power_button_ GUARDED_BY(m_);
 };
 
 }  // namespace vnc
diff --git a/host/frontend/vnc_server/vnc_client_connection.cpp b/host/frontend/vnc_server/vnc_client_connection.cpp
index 83ba5be..d69a510 100644
--- a/host/frontend/vnc_server/vnc_client_connection.cpp
+++ b/host/frontend/vnc_server/vnc_client_connection.cpp
@@ -1,13 +1,9 @@
 #include "vnc_client_connection.h"
 #include "keysyms.h"
+#include "mocks.h"
 #include "tcp_socket.h"
 #include "vnc_utils.h"
 
-#include <GceFrameBuffer.h>
-#include <gce_sensors_message.h>
-#include <sensors.h>
-#include "InitialMetadataReader.h"
-
 #include <netinet/in.h>
 #include <sys/time.h>
 
@@ -25,8 +21,8 @@
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
-#define LOG_TAG "GceVNCServer"
-#include <cutils/log.h>
+#define LOG_TAG "VSoCVNCServer"
+#include <glog/logging.h>
 
 using avd::vnc::Message;
 using avd::vnc::Stripe;
@@ -102,7 +98,9 @@
 }
 
 std::string HostName() {
-  return avd::InitialMetadataReader::getInstance()->GetInstanceHostname();
+  // Localhost is good enough for local development and to connect through ssh
+  // tunneling, for something else this probably needs to change.
+  return "localhost";
 }
 
 std::uint16_t uint16_tAt(const void* p) {
@@ -178,24 +176,29 @@
 }
 
 void VncClientConnection::StartSession() {
+  LOG(INFO) << "Starting session";
   SetupProtocol();
+  LOG(INFO) << "Protocol set up";
   if (client_.closed()) {
     return;
   }
   SetupSecurityType();
+  LOG(INFO) << "Security type set";
   if (client_.closed()) {
     return;
   }
   GetClientInit();
+  LOG(INFO) << "Gotten client init";
   if (client_.closed()) {
     return;
   }
   SendServerInit();
+  LOG(INFO) << "Sent server init";
   if (client_.closed()) {
     return;
   }
   NormalSession();
-  ALOGI("vnc session terminated");
+  LOG(INFO) << "vnc session terminated";
 }
 
 bool VncClientConnection::closed() {
@@ -211,8 +214,8 @@
   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]));
+    LOG(ERROR) << "vnc client wants a different protocol: "
+               << reinterpret_cast<const char*>(&client_protocol[0]);
   }
 }
 
@@ -226,8 +229,8 @@
     return;
   }
   if (client_security.front() != kNoneSecurity) {
-    ALOGE("vnc client is asking for security type %d",
-          static_cast<int>(client_security.front()));
+    LOG(ERROR) << "vnc client is asking for security type "
+               << static_cast<int>(client_security.front());
   }
   static constexpr std::uint8_t kZero[4] = {};
   client_.Send(kZero);
@@ -282,8 +285,8 @@
                     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);
+      LOG(FATAL) << "jpeg size is too big: " << jpeg_size << " must be under "
+                 << kJpegSizeThreeByteMax;
     }
     const auto sz = static_cast<std::uint32_t>(jpeg_size);
     AppendToMessage(frame_buffer_update,
@@ -301,7 +304,7 @@
   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());
+    CHECK((i + sizeof(Pixel)) < fbu.size());
     Pixel raw_pixel{};
     std::memcpy(&raw_pixel, &fbu[i], sizeof raw_pixel);
     auto red = RedVal(raw_pixel);
@@ -317,7 +320,7 @@
       std::swap(p[0], p[3]);
       std::swap(p[1], p[2]);
     }
-    ALOG_ASSERT(i + sizeof pixel <= fbu.size());
+    CHECK(i + sizeof pixel <= fbu.size());
     std::memcpy(&fbu[i], &pixel, sizeof pixel);
   }
 }
@@ -372,14 +375,18 @@
     if (closed()) {
       break;
     }
-    LOG_ALWAYS_FATAL_IF(stripes.empty(), "Got 0 stripes");
+    if (stripes.empty()) {
+      LOG(FATAL) << "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");
+      DLOG(INFO) << "Sending update in "
+                 << (current_orientation_ == ScreenOrientation::Portrait
+                         ? "portrait"
+                         : "landscape")
+                 << " mode";
       client_.Send(MakeFrameBufferUpdate(stripes));
     }
     if (aggressive) {
@@ -436,7 +443,7 @@
   }
   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);
+    DLOG(INFO) << "client requesting encoding: " << 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.
@@ -444,7 +451,7 @@
       use_jpeg_compression_ = true;
     }
     if (kJpegMinQualityEncoding <= enc && enc <= kJpegMaxQualityEncoding) {
-      D("jpeg compression level: %d", enc);
+      DLOG(INFO) << "jpeg compression level: " << enc;
       bb_->set_jpeg_quality_level(enc);
     }
     if (enc == kDesktopSizeEncoding) {
@@ -490,40 +497,41 @@
 }
 
 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()) {
-    ALOGE("sensor event client not open");
-    return;
-  }
-  timespec current_time{};
-  clock_gettime(CLOCK_MONOTONIC, &current_time);
-  // Construct the sensor message.
-  gce_sensors_message message{};
-  message.version = sizeof message;
-  message.sensor = avd::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;
+  // // 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, &current_time);
+  // // Construct the sensor message.
+  // gce_sensors_message message{};
+  // message.version = sizeof message;
+  // message.sensor = avd::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);
+  // 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) {
-    ALOGE("%s: Could not send sensor data. (%s).", __FUNCTION__,
-          sensor_event_hal_->StrError());
-  }
+  // 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();
+  // }
 }
 
 VncClientConnection::Coordinates VncClientConnection::CoordinatesForOrientation(
@@ -587,12 +595,12 @@
   switch (key) {
     case avd::xk::Right:
     case avd::xk::F12:
-      D("switching to portrait");
+      DLOG(INFO) << "switching to portrait";
       SetScreenOrientation(ScreenOrientation::Portrait);
       break;
     case avd::xk::Left:
     case avd::xk::F11:
-      D("switching to landscape");
+      DLOG(INFO) << "switching to landscape";
       SetScreenOrientation(ScreenOrientation::Landscape);
       break;
     default:
@@ -660,7 +668,7 @@
       return;
     }
     auto msg_type = msg.front();
-    D("Received message type %d\n", static_cast<int>(msg_type));
+    DLOG(INFO) << "Received message type " << msg_type;
 
     switch (msg_type) {
       case kSetPixelFormatMessage:
@@ -688,7 +696,8 @@
         break;
 
       default:
-        ALOGW("message type not handled: %d", static_cast<int>(msg_type));
+        LOG(WARNING) << "message type not handled: "
+                     << static_cast<int>(msg_type);
         break;
     }
   }
diff --git a/host/frontend/vnc_server/vnc_client_connection.h b/host/frontend/vnc_server/vnc_client_connection.h
index 749ebc4..d6b7f59 100644
--- a/host/frontend/vnc_server/vnc_client_connection.h
+++ b/host/frontend/vnc_server/vnc_client_connection.h
@@ -6,8 +6,8 @@
 #include "virtual_inputs.h"
 #include "vnc_utils.h"
 
-#include <SharedFD.h>
-#include <android-base/thread_annotations.h>
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/threads/thread_annotations.h"
 
 #include <cstdint>
 #include <memory>
diff --git a/host/frontend/vnc_server/vnc_server.cpp b/host/frontend/vnc_server/vnc_server.cpp
index 6852b69..838d51a 100644
--- a/host/frontend/vnc_server/vnc_server.cpp
+++ b/host/frontend/vnc_server/vnc_server.cpp
@@ -1,4 +1,5 @@
 #include "vnc_server.h"
+#include <glog/logging.h>
 #include "blackboard.h"
 #include "frame_buffer_watcher.h"
 #include "jpeg_compressor.h"
@@ -14,7 +15,9 @@
 
 void VncServer::MainLoop() {
   while (true) {
+    LOG(INFO) << "Awaiting connections";
     auto connection = server_.Accept();
+    LOG(INFO) << "Accepted a client connection";
     StartClient(std::move(connection));
   }
 }
diff --git a/host/frontend/vnc_server/vnc_utils.h b/host/frontend/vnc_server/vnc_utils.h
index 2782bbd..6c26cd6 100644
--- a/host/frontend/vnc_server/vnc_utils.h
+++ b/host/frontend/vnc_server/vnc_utils.h
@@ -1,19 +1,12 @@
 #ifndef DEVICE_GOOGLE_GCE_GCE_UTILS_GCE_VNC_SERVER_VNC_UTILS_H_
 #define DEVICE_GOOGLE_GCE_GCE_UTILS_GCE_VNC_SERVER_VNC_UTILS_H_
 
-#include <GceFrameBuffer.h>
-
 #include <array>
 #include <cstdint>
 #include <utility>
 #include <vector>
 
-#undef D
-#ifdef GCE_VNC_DEBUG
-#define D(...) ALOGD(__VA_ARGS__)
-#else
-#define D(...) ((void)0)
-#endif
+#include "common/vsoc/framebuffer/fb_bcast_region.h"
 
 namespace avd {
 namespace vnc {
@@ -54,14 +47,24 @@
   ScreenOrientation orientation{};
 };
 
-inline constexpr int BytesPerPixel() { return sizeof(GceFrameBuffer::Pixel); }
+inline int BytesPerPixel() {
+  return vsoc::framebuffer::FBBroadcastRegion::GetInstance()
+      ->display_properties()
+      .bytes_per_pixel();
+}
 
 // The width of the screen regardless of orientation. Does not change.
-inline int ActualScreenWidth() { return GceFrameBuffer::getInstance().x_res(); }
+inline int ActualScreenWidth() {
+  return vsoc::framebuffer::FBBroadcastRegion::GetInstance()
+      ->display_properties()
+      .x_res();
+}
 
 // The height of the screen regardless of orientation. Does not change.
 inline int ActualScreenHeight() {
-  return GceFrameBuffer::getInstance().y_res();
+  return vsoc::framebuffer::FBBroadcastRegion::GetInstance()
+      ->display_properties()
+      .y_res();
 }
 
 inline int ScreenSizeInBytes() {
diff --git a/host/vnc_server/Android.mk b/host/vnc_server/Android.mk
deleted file mode 100644
index 587986a..0000000
--- a/host/vnc_server/Android.mk
+++ /dev/null
@@ -1,89 +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/gce/sensors \
-    device/google/gce/include \
-    external/libjpeg-turbo \
-    external/jsoncpp/include
-
-include device/google/gce/libs/base/libbase.mk
-LOCAL_C_INCLUDES += $(GCE_LIBBASE_INCLUDE_DIR)
-
-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 \
-	tcp_socket.cpp \
-	VirtualInputDevice.cpp \
-	virtual_inputs.cpp \
-	vnc_client_connection.cpp \
-	vnc_server.cpp \
-
-LOCAL_CFLAGS := \
-	$(GCE_VERSION_CFLAGS) \
-	-std=gnu++11 \
-	-Wall -Werror \
-	-Wno-error-unused -Wno-error=unused-parameter \
-	-Wno-attributes \
-	-DGCE_32_BIT_GRAPHICS
-
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 18; echo $$?))
-LOCAL_CFLAGS += -Wno-error=implicit-exception-spec-mismatch
-endif
-
-LOCAL_SHARED_LIBRARIES := $(LIBJPEG_TURBO_NAME)
-LOCAL_STATIC_LIBRARIES := libcutils liblog
-LOCAL_CLANG := true
-
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -le 22; echo $$?)) #lmp-mr1 and down
-  LOCAL_STATIC_LIBRARIES += \
-    libgceframebuffer_cxx \
-    libgcemetadata_cxx \
-    libjsoncpp_cxx \
-    libgcecutils_cxx \
-
-  include external/libcxx/libcxx.mk
-else
-  LOCAL_STATIC_LIBRARIES += \
-    libgcemetadata \
-    libjsoncpp \
-
-  LOCAL_SHARED_LIBRARIES += \
-    libgceframebuffer \
-    libgcecutils \
-
-endif
-
-include $(BUILD_EXECUTABLE)