Merge "Make the AHardwareBuffer extension compatible with C."
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 7646feb..9e60461 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -294,7 +294,7 @@
 static const std::string &getArchString(Architecture arch) {
     static const std::string sStr64 = "64";
     static const std::string sStr32 = "32";
-    static const std::string sStrBoth = "64&32";
+    static const std::string sStrBoth = "32+64";
     static const std::string sStrUnknown = "";
     switch (arch) {
         case ARCH64:
@@ -325,12 +325,12 @@
     mServicesTable.description =
             "All binderized services (registered services through hwservicemanager)";
     mPassthroughRefTable.description =
-            "All interfaces that getService() has ever return a passthrough interface;\n"
+            "All interfaces that getService() has ever return as a passthrough interface;\n"
             "PIDs / processes shown below might be inaccurate because the process\n"
-            "might have relinquish the interface or might have died.\n"
+            "might have relinquished the interface or might have died.\n"
             "The Server / Server CMD column can be ignored.\n"
-            "The Clients / Clients CMD column shows all process that have ever dlopen the library\n"
-            "and successfully fetch the passthrough implementation.";
+            "The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
+            "the library and successfully fetched the passthrough implementation.";
     mImplementationsTable.description =
             "All available passthrough implementations (all -impl.so files)";
     forEachTable([this] (const Table &table) {
@@ -393,7 +393,7 @@
         for (const auto &info : infos) {
             std::string interfaceName = std::string{info.interfaceName.c_str()} + "/" +
                     std::string{info.instanceName.c_str()};
-            entries.emplace(std::string{interfaceName}, TableEntry{
+            entries.emplace(interfaceName, TableEntry{
                 .interfaceName = interfaceName,
                 .transport = "passthrough",
                 .serverPid = NO_PID,
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 3359c64..e52713f 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -126,6 +126,7 @@
         "EGL_EXT_yuv_surface "
         "EGL_EXT_protected_content "
         "EGL_IMG_context_priority "
+        "EGL_KHR_no_config_context "
         ;
 
 // extensions not exposed to applications but used by the ANDROID system
diff --git a/services/vr/virtual_touchpad/Android.mk b/services/vr/virtual_touchpad/Android.mk
index 4224aaa..b78eb99 100644
--- a/services/vr/virtual_touchpad/Android.mk
+++ b/services/vr/virtual_touchpad/Android.mk
@@ -6,13 +6,14 @@
 
 src := \
   EvdevInjector.cpp \
-  VirtualTouchpad.cpp
+  VirtualTouchpadEvdev.cpp
 
 shared_libs := \
   libbase
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(src)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_SHARED_LIBRARIES := $(shared_libs)
 LOCAL_CPPFLAGS += -std=c++11
 LOCAL_CFLAGS += -DLOG_TAG=\"VrVirtualTouchpad\"
@@ -29,11 +30,13 @@
 static_libs := \
   libbase \
   libcutils \
+  libutils \
   libvirtualtouchpad
 
 $(foreach file,$(test_src_files), \
     $(eval include $(CLEAR_VARS)) \
     $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_C_INCLUDES := $(LOCAL_PATH)/include) \
     $(eval LOCAL_STATIC_LIBRARIES := $(static_libs)) \
     $(eval LOCAL_SHARED_LIBRARIES := $(shared_libs)) \
     $(eval LOCAL_CPPFLAGS += -std=c++11) \
@@ -63,6 +66,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(src)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_STATIC_LIBRARIES := $(static_libs)
 LOCAL_SHARED_LIBRARIES := $(shared_libs)
 LOCAL_CPPFLAGS += -std=c++11
@@ -74,3 +78,27 @@
 LOCAL_MULTILIB := 64
 LOCAL_CXX_STL := libc++_static
 include $(BUILD_EXECUTABLE)
+
+
+# Touchpad client library.
+
+src := \
+  VirtualTouchpadClient.cpp \
+  aidl/android/dvr/VirtualTouchpadService.aidl
+
+shared_libs := \
+  libbase \
+  libbinder \
+  libutils
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(src)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_SHARED_LIBRARIES := $(shared_libs)
+LOCAL_CPPFLAGS += -std=c++11
+LOCAL_CFLAGS += -DLOG_TAG=\"VirtualTouchpadClient\"
+LOCAL_LDLIBS := -llog
+LOCAL_MODULE := libvirtualtouchpadclient
+LOCAL_MODULE_TAGS := optional
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+include $(BUILD_STATIC_LIBRARY)
diff --git a/services/vr/virtual_touchpad/VirtualTouchpad.h b/services/vr/virtual_touchpad/VirtualTouchpad.h
deleted file mode 100644
index 17aeb35..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpad.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_H
-
-#include <memory>
-
-#include "EvdevInjector.h"
-
-namespace android {
-namespace dvr {
-
-class EvdevInjector;
-
-// Provides a virtual touchpad for injecting events into the input system.
-//
-class VirtualTouchpad {
- public:
-  VirtualTouchpad() {}
-  ~VirtualTouchpad() {}
-
-  // |Intialize()| must be called once on a VirtualTouchpad before
-  // and other public method. Returns zero on success.
-  int Initialize();
-
-  // Generate a simulated touch event.
-  //
-  // @param x Horizontal touch position.
-  // @param y Vertical touch position.
-  //            Values must be in the range [0.0, 1.0).
-  // @param pressure Touch pressure.
-  //            Positive values represent contact; use 1.0f if contact
-  //            is binary. Use 0.0f for no contact.
-  // @returns Zero on success.
-  //
-  int Touch(float x, float y, float pressure);
-
-  // Generate a simulated touchpad button state.
-  //
-  // @param buttons A union of MotionEvent BUTTON_* values.
-  // @returns Zero on success.
-  //
-  // Currently only BUTTON_BACK is supported, as the implementation
-  // restricts itself to operations actually required by VrWindowManager.
-  //
-  int ButtonState(int buttons);
-
- protected:
-  // Must be called only between construction and Initialize().
-  inline void SetEvdevInjectorForTesting(EvdevInjector* injector) {
-    injector_ = injector;
-  }
-
- private:
-  // Except for testing, the |EvdevInjector| used to inject evdev events.
-  std::unique_ptr<EvdevInjector> owned_injector_;
-
-  // Active pointer to |owned_injector_| or to a testing injector.
-  EvdevInjector* injector_ = nullptr;
-
-  // Previous (x, y) position in device space, to suppress redundant events.
-  int32_t last_device_x_ = INT32_MIN;
-  int32_t last_device_y_ = INT32_MIN;
-
-  // Records current touch state (0=up 1=down) in bit 0, and previous state
-  // in bit 1, to track transitions.
-  int touches_ = 0;
-
-  // Previous injected button state, to detect changes.
-  int32_t last_motion_event_buttons_ = 0;
-
-  VirtualTouchpad(const VirtualTouchpad&) = delete;
-  void operator=(const VirtualTouchpad&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_H
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
new file mode 100644
index 0000000..23a2e31
--- /dev/null
+++ b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
@@ -0,0 +1,52 @@
+#include "VirtualTouchpadClient.h"
+
+#include <android/dvr/IVirtualTouchpadService.h>
+#include <binder/IServiceManager.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+class VirtualTouchpadClientImpl : public VirtualTouchpadClient {
+ public:
+  VirtualTouchpadClientImpl(sp<IVirtualTouchpadService> service)
+      : service_(service) {}
+  ~VirtualTouchpadClientImpl() {}
+
+  status_t Touch(float x, float y, float pressure) override {
+    if (service_ == nullptr) {
+      return NO_INIT;
+    }
+    return service_->touch(x, y, pressure).transactionError();
+  }
+  status_t ButtonState(int buttons) override {
+    if (service_ == nullptr) {
+      return NO_INIT;
+    }
+    return service_->buttonState(buttons).transactionError();
+  }
+
+ private:
+  sp<IVirtualTouchpadService> service_;
+};
+
+}  // anonymous namespace
+
+sp<VirtualTouchpad> VirtualTouchpadClient::Create() {
+  sp<IServiceManager> sm = defaultServiceManager();
+  if (sm == nullptr) {
+    ALOGE("no service manager");
+    return sp<VirtualTouchpad>();
+  }
+  sp<IVirtualTouchpadService> service = interface_cast<IVirtualTouchpadService>(
+      sm->getService(IVirtualTouchpadService::SERVICE_NAME()));
+  if (service == nullptr) {
+    ALOGE("failed to get service");
+    return sp<VirtualTouchpad>();
+  }
+  return new VirtualTouchpadClientImpl(service);
+}
+
+}  // namespace dvr
+}  // namespace android
diff --git a/services/vr/virtual_touchpad/VirtualTouchpad.cpp b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
similarity index 87%
rename from services/vr/virtual_touchpad/VirtualTouchpad.cpp
rename to services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
index 4793058..ae31156 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpad.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
@@ -1,4 +1,4 @@
-#include "VirtualTouchpad.h"
+#include "VirtualTouchpadEvdev.h"
 
 #include <android/input.h>
 #include <inttypes.h>
@@ -30,7 +30,17 @@
 
 }  // anonymous namespace
 
-int VirtualTouchpad::Initialize() {
+sp<VirtualTouchpad> VirtualTouchpadEvdev::Create() {
+  VirtualTouchpadEvdev* const touchpad = new VirtualTouchpadEvdev();
+  const status_t status = touchpad->Initialize();
+  if (status) {
+    ALOGE("initialization failed: %d", status);
+    return sp<VirtualTouchpad>();
+  }
+  return sp<VirtualTouchpad>(touchpad);
+}
+
+int VirtualTouchpadEvdev::Initialize() {
   if (!injector_) {
     owned_injector_.reset(new EvdevInjector());
     injector_ = owned_injector_.get();
@@ -46,7 +56,7 @@
   return injector_->GetError();
 }
 
-int VirtualTouchpad::Touch(float x, float y, float pressure) {
+int VirtualTouchpadEvdev::Touch(float x, float y, float pressure) {
   if ((x < 0.0f) || (x >= 1.0f) || (y < 0.0f) || (y >= 1.0f)) {
     return EINVAL;
   }
@@ -91,7 +101,7 @@
   return injector_->GetError();
 }
 
-int VirtualTouchpad::ButtonState(int buttons) {
+int VirtualTouchpadEvdev::ButtonState(int buttons) {
   const int changes = last_motion_event_buttons_ ^ buttons;
   if (!changes) {
     return 0;
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
new file mode 100644
index 0000000..c763529
--- /dev/null
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
@@ -0,0 +1,59 @@
+#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
+#define ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
+
+#include <memory>
+
+#include "VirtualTouchpad.h"
+#include "EvdevInjector.h"
+
+namespace android {
+namespace dvr {
+
+class EvdevInjector;
+
+// VirtualTouchpadEvdev implements a VirtualTouchpad by injecting evdev events.
+//
+class VirtualTouchpadEvdev : public VirtualTouchpad {
+ public:
+  static sp<VirtualTouchpad> Create();
+
+  // VirtualTouchpad implementation:
+  status_t Touch(float x, float y, float pressure) override;
+  status_t ButtonState(int buttons) override;
+
+ protected:
+  VirtualTouchpadEvdev() {}
+  ~VirtualTouchpadEvdev() {}
+  status_t Initialize();
+
+  // Must be called only between construction and Initialize().
+  inline void SetEvdevInjectorForTesting(EvdevInjector* injector) {
+    injector_ = injector;
+  }
+
+ private:
+  // Except for testing, the |EvdevInjector| used to inject evdev events.
+  std::unique_ptr<EvdevInjector> owned_injector_;
+
+  // Active pointer to |owned_injector_| or to a testing injector.
+  EvdevInjector* injector_ = nullptr;
+
+  // Previous (x, y) position in device space, to suppress redundant events.
+  int32_t last_device_x_ = INT32_MIN;
+  int32_t last_device_y_ = INT32_MIN;
+
+  // Records current touch state (0=up 1=down) in bit 0, and previous state
+  // in bit 1, to track transitions.
+  int touches_ = 0;
+
+  // Previous injected button state, to detect changes.
+  int32_t last_motion_event_buttons_ = 0;
+
+  VirtualTouchpadEvdev(const VirtualTouchpadEvdev&) = delete;
+  void operator=(const VirtualTouchpadEvdev&) = delete;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
index 25c1a4f..3fcb8fc 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
@@ -8,19 +8,15 @@
 namespace android {
 namespace dvr {
 
-int VirtualTouchpadService::Initialize() {
-  return touchpad_.Initialize();
-}
-
 binder::Status VirtualTouchpadService::touch(float x, float y, float pressure) {
-  const int error = touchpad_.Touch(x, y, pressure);
-  return error ? binder::Status::fromServiceSpecificError(error)
+  const status_t error = touchpad_->Touch(x, y, pressure);
+  return error ? binder::Status::fromStatusT(error)
                : binder::Status::ok();
 }
 
 binder::Status VirtualTouchpadService::buttonState(int buttons) {
-  const int error = touchpad_.ButtonState(buttons);
-  return error ? binder::Status::fromServiceSpecificError(error)
+  const status_t error = touchpad_->ButtonState(buttons);
+  return error ? binder::Status::fromStatusT(error)
                : binder::Status::ok();
 }
 
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.h b/services/vr/virtual_touchpad/VirtualTouchpadService.h
index e2426e3..b832c8f 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.h
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.h
@@ -13,22 +13,16 @@
 //
 class VirtualTouchpadService : public BnVirtualTouchpadService {
  public:
-  VirtualTouchpadService(VirtualTouchpad& touchpad)
+  VirtualTouchpadService(sp<VirtualTouchpad> touchpad)
       : touchpad_(touchpad) {}
 
-  // Must be called before clients can connect.
-  // Returns 0 if initialization is successful.
-  int Initialize();
-
-  static char const* getServiceName() { return "virtual_touchpad"; }
-
  protected:
   // Implements IVirtualTouchpadService.
-  ::android::binder::Status touch(float x, float y, float pressure) override;
-  ::android::binder::Status buttonState(int buttons) override;
+  binder::Status touch(float x, float y, float pressure) override;
+  binder::Status buttonState(int buttons) override;
 
  private:
-  VirtualTouchpad& touchpad_;
+  sp<VirtualTouchpad> touchpad_;
 
   VirtualTouchpadService(const VirtualTouchpadService&) = delete;
   void operator=(const VirtualTouchpadService&) = delete;
diff --git a/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl b/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl
index e048837..c2044da 100644
--- a/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl
+++ b/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl
@@ -3,6 +3,8 @@
 /** @hide */
 interface VirtualTouchpadService
 {
+  const String SERVICE_NAME = "virtual_touchpad";
+
   /**
    * Generate a simulated touch event.
    *
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpad.h b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
new file mode 100644
index 0000000..bbaf69b
--- /dev/null
+++ b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
@@ -0,0 +1,57 @@
+#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
+#define ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace dvr {
+
+// Provides a virtual touchpad for injecting events into the input system.
+//
+class VirtualTouchpad : public RefBase {
+ public:
+  // Create a virtual touchpad.
+  // Implementations should provide this, and hide their constructors.
+  // For the user, switching implementations should be as simple as changing
+  // the class whose |Create()| is called.
+  static sp<VirtualTouchpad> Create() {
+    return sp<VirtualTouchpad>();
+  }
+
+  // Generate a simulated touch event.
+  //
+  // @param x Horizontal touch position.
+  // @param y Vertical touch position.
+  //            Values must be in the range [0.0, 1.0).
+  // @param pressure Touch pressure.
+  //            Positive values represent contact; use 1.0f if contact
+  //            is binary. Use 0.0f for no contact.
+  // @returns OK on success.
+  //
+  virtual status_t Touch(float x, float y, float pressure) = 0;
+
+  // Generate a simulated touchpad button state.
+  //
+  // @param buttons A union of MotionEvent BUTTON_* values.
+  // @returns OK on success.
+  //
+  // Currently only BUTTON_BACK is supported, as the implementation
+  // restricts itself to operations actually required by VrWindowManager.
+  //
+  virtual status_t ButtonState(int buttons) = 0;
+
+ protected:
+  VirtualTouchpad() {}
+  virtual ~VirtualTouchpad() {}
+
+ private:
+  VirtualTouchpad(const VirtualTouchpad&) = delete;
+  void operator=(const VirtualTouchpad&) = delete;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
new file mode 100644
index 0000000..46bec0e
--- /dev/null
+++ b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
@@ -0,0 +1,31 @@
+#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
+#define ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
+
+#include "VirtualTouchpad.h"
+
+namespace android {
+namespace dvr {
+
+// VirtualTouchpadClient implements a VirtualTouchpad by connecting to
+// a VirtualTouchpadService over Binder.
+//
+class VirtualTouchpadClient : public VirtualTouchpad {
+ public:
+  // VirtualTouchpad implementation:
+  static sp<VirtualTouchpad> Create();
+  status_t Touch(float x, float y, float pressure) override;
+  status_t ButtonState(int buttons) override;
+
+ protected:
+  VirtualTouchpadClient() {}
+  virtual ~VirtualTouchpadClient() {}
+
+ private:
+  VirtualTouchpadClient(const VirtualTouchpadClient&) = delete;
+  void operator=(const VirtualTouchpadClient&) = delete;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
diff --git a/services/vr/virtual_touchpad/main.cpp b/services/vr/virtual_touchpad/main.cpp
index 1debe9f..e73f8b9 100644
--- a/services/vr/virtual_touchpad/main.cpp
+++ b/services/vr/virtual_touchpad/main.cpp
@@ -3,17 +3,13 @@
 #include <binder/ProcessState.h>
 #include <log/log.h>
 
+#include "VirtualTouchpadEvdev.h"
 #include "VirtualTouchpadService.h"
 
 int main() {
   ALOGI("Starting");
-  android::dvr::VirtualTouchpad touchpad;
-  android::dvr::VirtualTouchpadService touchpad_service(touchpad);
-  const int touchpad_status = touchpad_service.Initialize();
-  if (touchpad_status) {
-    ALOGE("virtual touchpad initialization failed: %d", touchpad_status);
-    exit(1);
-  }
+  android::dvr::VirtualTouchpadService touchpad_service(
+      android::dvr::VirtualTouchpadEvdev::Create());
 
   signal(SIGPIPE, SIG_IGN);
   android::sp<android::ProcessState> ps(android::ProcessState::self());
@@ -23,7 +19,7 @@
 
   android::sp<android::IServiceManager> sm(android::defaultServiceManager());
   const android::status_t service_status =
-      sm->addService(android::String16(touchpad_service.getServiceName()),
+      sm->addService(android::String16(touchpad_service.SERVICE_NAME()),
                      &touchpad_service, false /*allowIsolated*/);
   if (service_status != android::OK) {
     ALOGE("virtual touchpad service not added: %d",
diff --git a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
index 256c6bc..b448fd1 100644
--- a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
+++ b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
@@ -1,12 +1,12 @@
 #include <android/input.h>
+#include <gtest/gtest.h>
+#include <linux/input.h>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
-#include <gtest/gtest.h>
-#include <linux/input.h>
 
 #include "EvdevInjector.h"
-#include "VirtualTouchpad.h"
+#include "VirtualTouchpadEvdev.h"
 
 namespace android {
 namespace dvr {
@@ -21,7 +21,7 @@
     event.type = type;
     event.code = code;
     event.value = value;
-    Write(&event, sizeof (event));
+    Write(&event, sizeof(event));
   }
 };
 
@@ -87,16 +87,17 @@
 
 class EvdevInjectorForTesting : public EvdevInjector {
  public:
-  EvdevInjectorForTesting(UInput& uinput) {
-    SetUInputForTesting(&uinput);
-  }
+  EvdevInjectorForTesting(UInput& uinput) { SetUInputForTesting(&uinput); }
   const uinput_user_dev* GetUiDev() const { return GetUiDevForTesting(); }
 };
 
-class VirtualTouchpadForTesting : public VirtualTouchpad {
+class VirtualTouchpadForTesting : public VirtualTouchpadEvdev {
  public:
-  VirtualTouchpadForTesting(EvdevInjector& injector) {
-    SetEvdevInjectorForTesting(&injector);
+  static sp<VirtualTouchpad> Create(EvdevInjectorForTesting& injector) {
+    VirtualTouchpadForTesting* const touchpad = new VirtualTouchpadForTesting();
+    touchpad->SetEvdevInjectorForTesting(&injector);
+    touchpad->Initialize();
+    return sp<VirtualTouchpad>(touchpad);
   }
 };
 
@@ -113,17 +114,13 @@
 
 }  // anonymous namespace
 
-class VirtualTouchpadTest : public testing::Test {
-};
+class VirtualTouchpadTest : public testing::Test {};
 
 TEST_F(VirtualTouchpadTest, Goodness) {
   UInputRecorder expect;
   UInputRecorder record;
   EvdevInjectorForTesting injector(record);
-  VirtualTouchpadForTesting touchpad(injector);
-
-  const int initialization_status = touchpad.Initialize();
-  EXPECT_EQ(0, initialization_status);
+  sp<VirtualTouchpad> touchpad(VirtualTouchpadForTesting::Create(injector));
 
   // Check some aspects of uinput_user_dev.
   const uinput_user_dev* uidev = injector.GetUiDev();
@@ -154,13 +151,13 @@
   expect.IoctlSetInt(UI_SET_EVBIT, EV_KEY);
   expect.IoctlSetInt(UI_SET_KEYBIT, BTN_TOUCH);
   // From ConfigureEnd():
-  expect.Write(uidev, sizeof (uinput_user_dev));
+  expect.Write(uidev, sizeof(uinput_user_dev));
   expect.IoctlVoid(UI_DEV_CREATE);
   EXPECT_EQ(expect.GetString(), record.GetString());
 
   expect.Reset();
   record.Reset();
-  int touch_status = touchpad.Touch(0, 0, 0);
+  int touch_status = touchpad->Touch(0, 0, 0);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_ABS, ABS_MT_SLOT, 0);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
@@ -171,7 +168,7 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.Touch(0.25f, 0.75f, 0.5f);
+  touch_status = touchpad->Touch(0.25f, 0.75f, 0.5f);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
   expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.25f * width);
@@ -182,7 +179,7 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.Touch(1.0f, 1.0f, 1.0f);
+  touch_status = touchpad->Touch(1.0f, 1.0f, 1.0f);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
   expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, width);
@@ -192,7 +189,7 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.Touch(0.25f, 0.75f, -0.01f);
+  touch_status = touchpad->Touch(0.25f, 0.75f, -0.01f);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_RELEASE);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, -1);
@@ -201,7 +198,7 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.ButtonState(AMOTION_EVENT_BUTTON_BACK);
+  touch_status = touchpad->ButtonState(AMOTION_EVENT_BUTTON_BACK);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_PRESS);
   expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
@@ -209,13 +206,13 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.ButtonState(AMOTION_EVENT_BUTTON_BACK);
+  touch_status = touchpad->ButtonState(AMOTION_EVENT_BUTTON_BACK);
   EXPECT_EQ(0, touch_status);
   EXPECT_EQ(expect.GetString(), record.GetString());
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.ButtonState(0);
+  touch_status = touchpad->ButtonState(0);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_RELEASE);
   expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
@@ -229,56 +226,29 @@
   UInputRecorder expect;
   UInputRecorder record;
   EvdevInjectorForTesting injector(record);
-  VirtualTouchpadForTesting touchpad(injector);
-
-  // Touch before initialization should return an error,
-  // and should not result in any system calls.
-  expect.Reset();
-  record.Reset();
-  int touch_status = touchpad.Touch(0.25f, 0.75f, -0.01f);
-  EXPECT_NE(0, touch_status);
-  EXPECT_EQ(expect.GetString(), record.GetString());
-
-  // Button change before initialization should return an error,
-  // and should not result in any system calls.
-  expect.Reset();
-  record.Reset();
-  touch_status = touchpad.ButtonState(AMOTION_EVENT_BUTTON_BACK);
-  EXPECT_NE(0, touch_status);
-  EXPECT_EQ(expect.GetString(), record.GetString());
-
-  expect.Reset();
-  record.Reset();
-  touchpad.Initialize();
-
-  // Repeated initialization should return an error,
-  // and should not result in any system calls.
-  expect.Reset();
-  record.Reset();
-  const int initialization_status = touchpad.Initialize();
-  EXPECT_NE(0, initialization_status);
-  EXPECT_EQ(expect.GetString(), record.GetString());
+  sp<VirtualTouchpad> touchpad(
+      VirtualTouchpadForTesting::Create(injector));
 
   // Touch off-screen should return an error,
   // and should not result in any system calls.
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.Touch(-0.25f, 0.75f, 1.0f);
-  EXPECT_NE(0, touch_status);
-  touch_status = touchpad.Touch(0.25f, -0.75f, 1.0f);
-  EXPECT_NE(0, touch_status);
-  touch_status = touchpad.Touch(1.25f, 0.75f, 1.0f);
-  EXPECT_NE(0, touch_status);
-  touch_status = touchpad.Touch(0.25f, 1.75f, 1.0f);
-  EXPECT_NE(0, touch_status);
+  status_t touch_status = touchpad->Touch(-0.25f, 0.75f, 1.0f);
+  EXPECT_NE(OK, touch_status);
+  touch_status = touchpad->Touch(0.25f, -0.75f, 1.0f);
+  EXPECT_NE(OK, touch_status);
+  touch_status = touchpad->Touch(1.25f, 0.75f, 1.0f);
+  EXPECT_NE(OK, touch_status);
+  touch_status = touchpad->Touch(0.25f, 1.75f, 1.0f);
+  EXPECT_NE(OK, touch_status);
   EXPECT_EQ(expect.GetString(), record.GetString());
 
   // Unsupported button should return an error,
   // and should not result in any system calls.
   expect.Reset();
   record.Reset();
-  touch_status = touchpad.ButtonState(AMOTION_EVENT_BUTTON_FORWARD);
-  EXPECT_NE(0, touch_status);
+  touch_status = touchpad->ButtonState(AMOTION_EVENT_BUTTON_FORWARD);
+  EXPECT_NE(OK, touch_status);
   EXPECT_EQ(expect.GetString(), record.GetString());
 }
 
diff --git a/services/vr/vr_window_manager/Android.mk b/services/vr/vr_window_manager/Android.mk
index 706efe5..ddb58e9 100644
--- a/services/vr/vr_window_manager/Android.mk
+++ b/services/vr/vr_window_manager/Android.mk
@@ -14,29 +14,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-binder_src := \
-  vr_window_manager_binder.cpp \
-  aidl/android/service/vr/IVrWindowManager.aidl
-
-static_libs := \
-  libcutils
-
-shared_libs := \
-  libbase \
-  libbinder \
-  libutils
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(binder_src)
-LOCAL_STATIC_LIBRARIES := $(static_libs)
-LOCAL_SHARED_LIBRARIES := $(shared_libs)
-LOCAL_CPPFLAGS += -std=c++11
-LOCAL_CFLAGS += -DLOG_TAG=\"VrWindowManager\"
-LOCAL_LDLIBS := -llog
-LOCAL_MODULE := libvrwm_binder
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_STATIC_LIBRARY)
-
 native_src := \
   application.cpp \
   controller_mesh.cpp \
@@ -47,7 +24,8 @@
   surface_flinger_view.cpp \
   texture.cpp \
   vr_window_manager.cpp \
-  ../virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl \
+  vr_window_manager_binder.cpp \
+  aidl/android/service/vr/IVrWindowManager.aidl
 
 static_libs := \
   libdisplay \
@@ -62,6 +40,7 @@
   libpdx_default_transport \
   libcutils \
   libvr_manager \
+  libvirtualtouchpadclient
 
 shared_libs := \
   android.dvr.composer@1.0 \
@@ -85,7 +64,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(native_src)
-LOCAL_STATIC_LIBRARIES := $(static_libs) libvrwm_binder
+LOCAL_STATIC_LIBRARIES := $(static_libs)
 LOCAL_SHARED_LIBRARIES := $(shared_libs)
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
 LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index 6cbd88d..7321ed0 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -703,10 +703,7 @@
 }
 
 bool ShellView::InitializeTouch() {
-  virtual_touchpad_ =
-      android::interface_cast<android::dvr::IVirtualTouchpadService>(
-          android::defaultServiceManager()->getService(
-              android::String16("virtual_touchpad")));
+  virtual_touchpad_ = VirtualTouchpadClient::Create();
   if (!virtual_touchpad_.get()) {
     ALOGE("Failed to connect to virtual touchpad");
     return false;
@@ -723,12 +720,12 @@
     }
   }
 
-  const android::binder::Status status = virtual_touchpad_->touch(
+  const android::status_t status = virtual_touchpad_->Touch(
       hit_location_in_window_coord_.x() / size_.x(),
       hit_location_in_window_coord_.y() / size_.y(),
       is_touching_ ? 1.0f : 0.0f);
-  if (!status.isOk()) {
-    ALOGE("touch failed: %s", status.toString8().string());
+  if (status != OK) {
+    ALOGE("touch failed: %d", status);
   }
 }
 
@@ -750,11 +747,10 @@
     return false;
   }
 
-  const android::binder::Status status =
-      virtual_touchpad_->buttonState(touchpad_buttons_);
-  if (!status.isOk()) {
-    ALOGE("touchpad button failed: %d %s", touchpad_buttons_,
-          status.toString8().string());
+  const android::status_t status =
+      virtual_touchpad_->ButtonState(touchpad_buttons_);
+  if (status != OK) {
+    ALOGE("touchpad button failed: %d %d", touchpad_buttons_, status);
   }
   return true;
 }
diff --git a/services/vr/vr_window_manager/shell_view.h b/services/vr/vr_window_manager/shell_view.h
index 1e061bb..c477669 100644
--- a/services/vr/vr_window_manager/shell_view.h
+++ b/services/vr/vr_window_manager/shell_view.h
@@ -3,10 +3,10 @@
 
 #include <private/dvr/graphics/mesh.h>
 #include <private/dvr/graphics/shader_program.h>
-#include <android/dvr/IVirtualTouchpadService.h>
 
 #include <deque>
 
+#include "VirtualTouchpadClient.h"
 #include "application.h"
 #include "reticle.h"
 #include "shell_view_binder_interface.h"
@@ -90,7 +90,7 @@
 
   std::unique_ptr<SurfaceFlingerView> surface_flinger_view_;
   std::unique_ptr<Reticle> reticle_;
-  sp<IVirtualTouchpadService> virtual_touchpad_;
+  sp<VirtualTouchpad> virtual_touchpad_;
   std::vector<TextureLayer> textures_;
   TextureLayer ime_texture_;
 
diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h
index f12395f..3c8ee1c 100644
--- a/vulkan/include/vulkan/vulkan.h
+++ b/vulkan/include/vulkan/vulkan.h
@@ -3713,7 +3713,7 @@
     VkStructureType                   sType;
     const void*                       pNext;
     VkAndroidSurfaceCreateFlagsKHR    flags;
-    ANativeWindow*                    window;
+    struct ANativeWindow*             window;
 } VkAndroidSurfaceCreateInfoKHR;
 
 
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 358645c..a0ae1f3 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -479,7 +479,7 @@
               err);
         surface->~Surface();
         allocator->pfnFree(allocator->pUserData, surface);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
     }
 
     *out_surface = HandleFromSurface(surface);
@@ -527,13 +527,13 @@
     if (err != 0) {
         ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
     err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
     if (err != 0) {
         ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     int transform_hint;
@@ -541,7 +541,7 @@
     if (err != 0) {
         ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     // TODO(jessehall): Figure out what the min/max values should be.
@@ -764,7 +764,7 @@
     if (err != 0) {
         ALOGE("native_window_set_buffer_count(0) failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     int swap_interval =
@@ -775,21 +775,21 @@
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window->setSwapInterval(1) failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     err = native_window_set_shared_buffer_mode(surface.window.get(), false);
     if (err != 0) {
         ALOGE("native_window_set_shared_buffer_mode(false) failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     err = native_window_set_auto_refresh(surface.window.get(), false);
     if (err != 0) {
         ALOGE("native_window_set_auto_refresh(false) failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     // -- Configure the native window --
@@ -803,7 +803,7 @@
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_buffers_format(%d) failed: %s (%d)",
               native_pixel_format, strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
     err = native_window_set_buffers_data_space(surface.window.get(),
                                                native_dataspace);
@@ -812,7 +812,7 @@
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_buffers_data_space(%d) failed: %s (%d)",
               native_dataspace, strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     err = native_window_set_buffers_dimensions(
@@ -824,7 +824,7 @@
         ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
               create_info->imageExtent.width, create_info->imageExtent.height,
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     // VkSwapchainCreateInfo::preTransform indicates the transformation the app
@@ -844,7 +844,7 @@
         ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
               InvertTransformToNative(create_info->preTransform),
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     err = native_window_set_scaling_mode(
@@ -854,7 +854,7 @@
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_scaling_mode(SCALE_TO_WINDOW) failed: %s (%d)",
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     int query_value;
@@ -866,7 +866,7 @@
         // errors and translate them to valid Vulkan result codes?
         ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
               query_value);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
     uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
     uint32_t num_images =
@@ -877,7 +877,7 @@
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_buffer_count(%d) failed: %s (%d)", num_images,
               strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     VkSwapchainImageUsageFlagsANDROID swapchain_image_usage = 0;
@@ -888,7 +888,7 @@
         err = native_window_set_shared_buffer_mode(surface.window.get(), true);
         if (err != 0) {
             ALOGE("native_window_set_shared_buffer_mode failed: %s (%d)", strerror(-err), err);
-            return VK_ERROR_INITIALIZATION_FAILED;
+            return VK_ERROR_SURFACE_LOST_KHR;
         }
     }
 
@@ -896,7 +896,7 @@
         err = native_window_set_auto_refresh(surface.window.get(), true);
         if (err != 0) {
             ALOGE("native_window_set_auto_refresh failed: %s (%d)", strerror(-err), err);
-            return VK_ERROR_INITIALIZATION_FAILED;
+            return VK_ERROR_SURFACE_LOST_KHR;
         }
     }
 
@@ -925,7 +925,7 @@
         }
         if (result != VK_SUCCESS) {
             ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result);
-            return VK_ERROR_INITIALIZATION_FAILED;
+            return VK_ERROR_SURFACE_LOST_KHR;
         }
         // TODO: This is the same translation done by Gralloc1On0Adapter.
         // Remove it once ANativeWindow has been updated to take gralloc1-style
@@ -938,7 +938,7 @@
             &gralloc_usage);
         if (result != VK_SUCCESS) {
             ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
-            return VK_ERROR_INITIALIZATION_FAILED;
+            return VK_ERROR_SURFACE_LOST_KHR;
         }
     }
     err = native_window_set_usage(surface.window.get(), gralloc_usage);
@@ -946,7 +946,7 @@
         // TODO(jessehall): Improve error reporting. Can we enumerate possible
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     // -- Allocate our Swapchain object --
@@ -1005,7 +1005,7 @@
             // TODO(jessehall): Improve error reporting. Can we enumerate
             // possible errors and translate them to valid Vulkan result codes?
             ALOGE("dequeueBuffer[%u] failed: %s (%d)", i, strerror(-err), err);
-            result = VK_ERROR_INITIALIZATION_FAILED;
+            result = VK_ERROR_SURFACE_LOST_KHR;
             break;
         }
         img.buffer = buffer;
@@ -1141,7 +1141,7 @@
         // TODO(jessehall): Improve error reporting. Can we enumerate possible
         // errors and translate them to valid Vulkan result codes?
         ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err);
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_ERROR_SURFACE_LOST_KHR;
     }
 
     uint32_t idx;