Merge "[SurfaceFlinger] Comment SurfaceFlinger HWC2"
diff --git a/cmds/bugreportz/readme.md b/cmds/bugreportz/readme.md
index 2697f09..eb0d898 100644
--- a/cmds/bugreportz/readme.md
+++ b/cmds/bugreportz/readme.md
@@ -17,3 +17,4 @@
 
 - `OK:<path_to_bugreport_file>` in case of success.
 - `FAIL:<error message>` in case of failure.
+
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index a84b051..fbb30db 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1252,7 +1252,7 @@
             calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
                     sharedGid, -1);
         }
-        calculate_tree_size(create_data_misc_foreign_dex_path(userId), &stats.dataSize,
+        calculate_tree_size(create_data_user_profile_path(userId), &stats.dataSize,
                 multiuser_get_uid(userId, appId), -1);
         ATRACE_END();
     }
@@ -1350,7 +1350,7 @@
         ATRACE_BEGIN("dalvik");
         calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
                 -1, -1, true);
-        calculate_tree_size(create_data_misc_foreign_dex_path(userId), &stats.dataSize,
+        calculate_tree_size(create_data_user_profile_path(userId), &stats.dataSize,
                 -1, -1, true);
         ATRACE_END();
 
@@ -1400,7 +1400,7 @@
 
         ATRACE_BEGIN("dalvik");
         calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
-        calculate_tree_size(create_data_misc_foreign_dex_path(userId), &stats.dataSize);
+        calculate_tree_size(create_data_user_profile_path(userId), &stats.dataSize);
         ATRACE_END();
     }
 
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 6d50f55..2bf0171 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -239,10 +239,6 @@
     return "/data/dalvik-cache";
 }
 
-std::string create_data_misc_foreign_dex_path(userid_t userid) {
-    return StringPrintf("/data/misc/profiles/cur/%d/foreign-dex", userid);
-}
-
 // Keep profile paths in sync with ActivityThread.
 constexpr const char* PRIMARY_PROFILE_NAME = "primary.prof";
 
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index aa83dc2..d99b445 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -103,7 +103,6 @@
 std::string create_data_ref_profile_package_path(const char* package_name);
 
 std::string create_data_dalvik_cache_path();
-std::string create_data_misc_foreign_dex_path(userid_t userid);
 
 std::string create_primary_profile(const std::string& profile_dir);
 
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/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h
index f757fc3..f36c9fd 100644
--- a/cmds/surfacereplayer/replayer/Replayer.h
+++ b/cmds/surfacereplayer/replayer/Replayer.h
@@ -29,6 +29,7 @@
 #include <utils/Errors.h>
 #include <utils/StrongPointer.h>
 
+#include <stdatomic.h>
 #include <condition_variable>
 #include <memory>
 #include <mutex>
diff --git a/include/gui/BitTube.h b/include/private/gui/BitTube.h
similarity index 100%
rename from include/gui/BitTube.h
rename to include/private/gui/BitTube.h
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index f4e0a60..5c1a4f4 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -17,6 +17,8 @@
 #define LOG_TAG "IMemory"
 
 #include <atomic>
+#include <stdatomic.h>
+
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -28,6 +30,7 @@
 #include <binder/IMemory.h>
 #include <binder/Parcel.h>
 #include <log/log.h>
+
 #include <utils/CallStack.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 8f9c38a..a1b4abc 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -38,10 +38,6 @@
         // Don't warn about struct padding
         "-Wno-padded",
 
-        // android/sensors.h uses nested anonymous unions and anonymous structs
-        "-Wno-nested-anon-types",
-        "-Wno-gnu-anonymous-struct",
-
         // We are aware of the risks inherent in comparing floats for equality
         "-Wno-float-equal",
 
@@ -61,8 +57,6 @@
     },
 
     srcs: [
-        "IGraphicBufferConsumer.cpp",
-        "IConsumerListener.cpp",
         "BitTube.cpp",
         "BufferItem.cpp",
         "BufferItemConsumer.cpp",
@@ -79,18 +73,15 @@
         "GraphicBufferAlloc.cpp",
         "GuiConfig.cpp",
         "IDisplayEventConnection.cpp",
+        "IConsumerListener.cpp",
         "IGraphicBufferAlloc.cpp",
+        "IGraphicBufferConsumer.cpp",
         "IGraphicBufferProducer.cpp",
         "IProducerListener.cpp",
-        "ISensorEventConnection.cpp",
-        "ISensorServer.cpp",
         "ISurfaceComposer.cpp",
         "ISurfaceComposerClient.cpp",
         "LayerState.cpp",
         "OccupancyTracker.cpp",
-        "Sensor.cpp",
-        "SensorEventQueue.cpp",
-        "SensorManager.cpp",
         "StreamSplitter.cpp",
         "Surface.cpp",
         "SurfaceControl.cpp",
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index b653c5b..51a8d67 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <private/gui/BitTube.h>
+
 #include <stdint.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -25,7 +27,6 @@
 
 #include <binder/Parcel.h>
 
-#include <gui/BitTube.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 6e6cce2..9e3fecb 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -29,6 +29,7 @@
 #include <inttypes.h>
 
 #include <cutils/properties.h>
+#include <cutils/atomic.h>
 
 #include <gui/BufferItem.h>
 #include <gui/BufferQueueCore.h>
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index c26de66..8acdfed 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -27,6 +27,8 @@
 
 #include <hardware/hardware.h>
 
+#include <cutils/atomic.h>
+
 #include <gui/BufferItem.h>
 #include <gui/IGraphicBufferAlloc.h>
 #include <gui/ISurfaceComposer.h>
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index 9973e8d..07e07e0 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -18,13 +18,14 @@
 
 #include <utils/Errors.h>
 
-#include <gui/BitTube.h>
 #include <gui/DisplayEventReceiver.h>
 #include <gui/IDisplayEventConnection.h>
 #include <gui/ISurfaceComposer.h>
 
 #include <private/gui/ComposerService.h>
 
+#include <private/gui/BitTube.h>
+
 // ---------------------------------------------------------------------------
 
 namespace android {
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
index b1d3b00..e5c3c48 100644
--- a/libs/gui/IDisplayEventConnection.cpp
+++ b/libs/gui/IDisplayEventConnection.cpp
@@ -15,17 +15,15 @@
  */
 
 #include <stdint.h>
-#include <sys/types.h>
 
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
-#include <utils/Timers.h>
 
 #include <binder/Parcel.h>
-#include <binder/IInterface.h>
 
 #include <gui/IDisplayEventConnection.h>
-#include <gui/BitTube.h>
+
+#include <private/gui/BitTube.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 5944110..4492a08 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -14,7 +14,6 @@
         "GLTest.cpp",
         "IGraphicBufferProducer_test.cpp",
         "MultiTextureConsumer_test.cpp",
-        "Sensor_test.cpp",
         "StreamSplitter_test.cpp",
         "SurfaceTextureClient_test.cpp",
         "SurfaceTextureFBO_test.cpp",
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 9485d5b..9294419 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -17,7 +17,11 @@
 cc_library {
     name: "libinput",
     host_supported: true,
-
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
     srcs: [
         "Input.cpp",
         "InputDevice.cpp",
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 9d761fd..4287abe 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -90,7 +90,7 @@
     String8 path;
 
     // Treblized input device config files will be located /odm/usr or /vendor/usr.
-    char *rootsForPartition[] {"/odm", "/vendor", getenv("ANDROID_ROOT")};
+    const char *rootsForPartition[] {"/odm", "/vendor", getenv("ANDROID_ROOT")};
     for (size_t i = 0; i < size(rootsForPartition); i++) {
         path.setTo(rootsForPartition[i]);
         path.append("/usr/");
diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp
index 9a01395..07f2289 100644
--- a/libs/input/Keyboard.cpp
+++ b/libs/input/Keyboard.cpp
@@ -208,7 +208,6 @@
 }
 
 int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
-    int32_t mask;
     switch (keyCode) {
     case AKEYCODE_ALT_LEFT:
         return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
new file mode 100644
index 0000000..171a627
--- /dev/null
+++ b/libs/sensor/Android.bp
@@ -0,0 +1,61 @@
+// Copyright 2010 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.
+
+cc_library_shared {
+    name: "libsensor",
+
+    clang: true,
+    cppflags: [
+        "-Weverything",
+        "-Werror",
+
+        // The static constructors and destructors in this library have not been noted to
+        // introduce significant overheads
+        "-Wno-exit-time-destructors",
+        "-Wno-global-constructors",
+
+        // We only care about compiling as C++14
+        "-Wno-c++98-compat-pedantic",
+
+        // android/sensors.h uses nested anonymous unions and anonymous structs
+        "-Wno-nested-anon-types",
+        "-Wno-gnu-anonymous-struct",
+
+        // Don't warn about struct padding
+        "-Wno-padded",
+    ],
+
+    srcs: [
+        "BitTube.cpp",
+        "ISensorEventConnection.cpp",
+        "ISensorServer.cpp",
+        "Sensor.cpp",
+        "SensorEventQueue.cpp",
+        "SensorManager.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libcutils",
+        "libutils",
+        "liblog",
+        "libhardware",
+    ],
+
+    export_include_dirs: ["include"],
+
+    export_shared_lib_headers: ["libbinder", "libhardware"],
+}
+
+subdirs = ["tests"]
diff --git a/libs/sensor/BitTube.cpp b/libs/sensor/BitTube.cpp
new file mode 100644
index 0000000..93555c8
--- /dev/null
+++ b/libs/sensor/BitTube.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensor/BitTube.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <binder/Parcel.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+// Socket buffer size.  The default is typically about 128KB, which is much larger than
+// we really need.  So we make it smaller.
+static const size_t DEFAULT_SOCKET_BUFFER_SIZE = 4 * 1024;
+
+
+BitTube::BitTube()
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    init(DEFAULT_SOCKET_BUFFER_SIZE, DEFAULT_SOCKET_BUFFER_SIZE);
+}
+
+BitTube::BitTube(size_t bufsize)
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    init(bufsize, bufsize);
+}
+
+BitTube::BitTube(const Parcel& data)
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    mReceiveFd = dup(data.readFileDescriptor());
+    if (mReceiveFd < 0) {
+        mReceiveFd = -errno;
+        ALOGE("BitTube(Parcel): can't dup filedescriptor (%s)",
+                strerror(-mReceiveFd));
+    }
+}
+
+BitTube::~BitTube()
+{
+    if (mSendFd >= 0)
+        close(mSendFd);
+
+    if (mReceiveFd >= 0)
+        close(mReceiveFd);
+}
+
+void BitTube::init(size_t rcvbuf, size_t sndbuf) {
+    int sockets[2];
+    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
+        size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
+        setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+        setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
+        // sine we don't use the "return channel", we keep it small...
+        setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
+        setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+        fcntl(sockets[0], F_SETFL, O_NONBLOCK);
+        fcntl(sockets[1], F_SETFL, O_NONBLOCK);
+        mReceiveFd = sockets[0];
+        mSendFd = sockets[1];
+    } else {
+        mReceiveFd = -errno;
+        ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
+    }
+}
+
+status_t BitTube::initCheck() const
+{
+    if (mReceiveFd < 0) {
+        return status_t(mReceiveFd);
+    }
+    return NO_ERROR;
+}
+
+int BitTube::getFd() const
+{
+    return mReceiveFd;
+}
+
+int BitTube::getSendFd() const
+{
+    return mSendFd;
+}
+
+ssize_t BitTube::write(void const* vaddr, size_t size)
+{
+    ssize_t err, len;
+    do {
+        len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
+        // cannot return less than size, since we're using SOCK_SEQPACKET
+        err = len < 0 ? errno : 0;
+    } while (err == EINTR);
+    return err == 0 ? len : -err;
+}
+
+ssize_t BitTube::read(void* vaddr, size_t size)
+{
+    ssize_t err, len;
+    do {
+        len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
+        err = len < 0 ? errno : 0;
+    } while (err == EINTR);
+    if (err == EAGAIN || err == EWOULDBLOCK) {
+        // EAGAIN means that we have non-blocking I/O but there was
+        // no data to be read. Nothing the client should care about.
+        return 0;
+    }
+    return err == 0 ? len : -err;
+}
+
+status_t BitTube::writeToParcel(Parcel* reply) const
+{
+    if (mReceiveFd < 0)
+        return -EINVAL;
+
+    status_t result = reply->writeDupFileDescriptor(mReceiveFd);
+    close(mReceiveFd);
+    mReceiveFd = -1;
+    return result;
+}
+
+
+ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
+        void const* events, size_t count, size_t objSize)
+{
+    const char* vaddr = reinterpret_cast<const char*>(events);
+    ssize_t size = tube->write(vaddr, count*objSize);
+
+    // should never happen because of SOCK_SEQPACKET
+    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
+            "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
+            count, objSize, size);
+
+    //ALOGE_IF(size<0, "error %d sending %d events", size, count);
+    return size < 0 ? size : size / static_cast<ssize_t>(objSize);
+}
+
+ssize_t BitTube::recvObjects(const sp<BitTube>& tube,
+        void* events, size_t count, size_t objSize)
+{
+    char* vaddr = reinterpret_cast<char*>(events);
+    ssize_t size = tube->read(vaddr, count*objSize);
+
+    // should never happen because of SOCK_SEQPACKET
+    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
+            "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)",
+            count, objSize, size);
+
+    //ALOGE_IF(size<0, "error %d receiving %d events", size, count);
+    return size < 0 ? size : size / static_cast<ssize_t>(objSize);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/sensor/ISensorEventConnection.cpp
similarity index 98%
rename from libs/gui/ISensorEventConnection.cpp
rename to libs/sensor/ISensorEventConnection.cpp
index 8af51c5..8a3a623 100644
--- a/libs/gui/ISensorEventConnection.cpp
+++ b/libs/sensor/ISensorEventConnection.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <sensor/ISensorEventConnection.h>
+
 #include <stdint.h>
 #include <sys/types.h>
 
@@ -24,8 +26,7 @@
 #include <binder/Parcel.h>
 #include <binder/IInterface.h>
 
-#include <gui/ISensorEventConnection.h>
-#include <gui/BitTube.h>
+#include <sensor/BitTube.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp
similarity index 98%
rename from libs/gui/ISensorServer.cpp
rename to libs/sensor/ISensorServer.cpp
index aea7403..f41f187 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/sensor/ISensorServer.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <sensor/ISensorServer.h>
+
 #include <stdint.h>
 #include <sys/types.h>
 
@@ -26,9 +28,8 @@
 #include <binder/Parcel.h>
 #include <binder/IInterface.h>
 
-#include <gui/Sensor.h>
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/ISensorEventConnection.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/Sensor.cpp b/libs/sensor/Sensor.cpp
similarity index 98%
rename from libs/gui/Sensor.cpp
rename to libs/sensor/Sensor.cpp
index e2f733a..c2d477e 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -14,19 +14,13 @@
  * limitations under the License.
  */
 
+#include <sensor/Sensor.h>
+
 #include <inttypes.h>
-#include <stdint.h>
-#include <sys/limits.h>
-#include <sys/types.h>
 
 #include <binder/AppOpsManager.h>
+#include <binder/IPermissionController.h>
 #include <binder/IServiceManager.h>
-#include <gui/Sensor.h>
-#include <hardware/sensors.h>
-#include <log/log.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/Flattenable.h>
 
 // ----------------------------------------------------------------------------
 namespace android {
@@ -51,7 +45,7 @@
     mHandle = hwSensor.handle;
     mType = hwSensor.type;
     mMinValue = 0;                      // FIXME: minValue
-    mMaxValue = hwSensor.maxRange;     // FIXME: maxValue
+    mMaxValue = hwSensor.maxRange;      // FIXME: maxValue
     mResolution = hwSensor.resolution;
     mPower = hwSensor.power;
     mMinDelay = hwSensor.minDelay;
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/sensor/SensorEventQueue.cpp
similarity index 96%
rename from libs/gui/SensorEventQueue.cpp
rename to libs/sensor/SensorEventQueue.cpp
index 6d69839..8ba3ebe 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/sensor/SensorEventQueue.cpp
@@ -16,20 +16,17 @@
 
 #define LOG_TAG "Sensors"
 
-#include <algorithm>
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <linux/errno.h>
+#include <sensor/SensorEventQueue.h>
 
-#include <utils/Errors.h>
+#include <algorithm>
+#include <sys/socket.h>
+
 #include <utils/RefBase.h>
 #include <utils/Looper.h>
 
-#include <gui/Sensor.h>
-#include <gui/BitTube.h>
-#include <gui/SensorEventQueue.h>
-#include <gui/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/BitTube.h>
+#include <sensor/ISensorEventConnection.h>
 
 #include <android/sensor.h>
 
diff --git a/libs/gui/SensorManager.cpp b/libs/sensor/SensorManager.cpp
similarity index 98%
rename from libs/gui/SensorManager.cpp
rename to libs/sensor/SensorManager.cpp
index 513b889..b6e9fa1 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -16,6 +16,8 @@
 
 #define LOG_TAG "Sensors"
 
+#include <sensor/SensorManager.h>
+
 #include <stdint.h>
 #include <sys/types.h>
 
@@ -27,11 +29,10 @@
 #include <binder/IBinder.h>
 #include <binder/IServiceManager.h>
 
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
-#include <gui/Sensor.h>
-#include <gui/SensorManager.h>
-#include <gui/SensorEventQueue.h>
+#include <sensor/ISensorServer.h>
+#include <sensor/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/SensorEventQueue.h>
 
 // ----------------------------------------------------------------------------
 namespace android {
diff --git a/libs/sensor/include/sensor/BitTube.h b/libs/sensor/include/sensor/BitTube.h
new file mode 100644
index 0000000..c1fabe8
--- /dev/null
+++ b/libs/sensor/include/sensor/BitTube.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+class Parcel;
+
+class BitTube : public RefBase
+{
+public:
+
+    // creates a BitTube with a default (4KB) send buffer
+    BitTube();
+
+    // creates a BitTube with a a specified send and receive buffer size
+    explicit BitTube(size_t bufsize);
+
+    explicit BitTube(const Parcel& data);
+    virtual ~BitTube();
+
+    // check state after construction
+    status_t initCheck() const;
+
+    // get receive file-descriptor
+    int getFd() const;
+
+    // get the send file-descriptor.
+    int getSendFd() const;
+
+    // send objects (sized blobs). All objects are guaranteed to be written or the call fails.
+    template <typename T>
+    static ssize_t sendObjects(const sp<BitTube>& tube,
+            T const* events, size_t count) {
+        return sendObjects(tube, events, count, sizeof(T));
+    }
+
+    // receive objects (sized blobs). If the receiving buffer isn't large enough,
+    // excess messages are silently discarded.
+    template <typename T>
+    static ssize_t recvObjects(const sp<BitTube>& tube,
+            T* events, size_t count) {
+        return recvObjects(tube, events, count, sizeof(T));
+    }
+
+    // parcels this BitTube
+    status_t writeToParcel(Parcel* reply) const;
+
+private:
+    void init(size_t rcvbuf, size_t sndbuf);
+
+    // send a message. The write is guaranteed to send the whole message or fail.
+    ssize_t write(void const* vaddr, size_t size);
+
+    // receive a message. the passed buffer must be at least as large as the
+    // write call used to send the message, excess data is silently discarded.
+    ssize_t read(void* vaddr, size_t size);
+
+    int mSendFd;
+    mutable int mReceiveFd;
+
+    static ssize_t sendObjects(const sp<BitTube>& tube,
+            void const* events, size_t count, size_t objSize);
+
+    static ssize_t recvObjects(const sp<BitTube>& tube,
+            void* events, size_t count, size_t objSize);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/include/gui/ISensorEventConnection.h b/libs/sensor/include/sensor/ISensorEventConnection.h
similarity index 91%
rename from include/gui/ISensorEventConnection.h
rename to libs/sensor/include/sensor/ISensorEventConnection.h
index 2ccd832..07cc7e8 100644
--- a/include/gui/ISensorEventConnection.h
+++ b/libs/sensor/include/sensor/ISensorEventConnection.h
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
-#define ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
 
 #include <binder/IInterface.h>
 
@@ -29,6 +29,7 @@
 // ----------------------------------------------------------------------------
 
 class BitTube;
+class Parcel;
 
 class ISensorEventConnection : public IInterface
 {
@@ -56,5 +57,3 @@
 
 // ----------------------------------------------------------------------------
 }; // namespace android
-
-#endif // ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
diff --git a/include/gui/ISensorServer.h b/libs/sensor/include/sensor/ISensorServer.h
similarity index 93%
rename from include/gui/ISensorServer.h
rename to libs/sensor/include/sensor/ISensorServer.h
index 0c36c99..f922307 100644
--- a/include/gui/ISensorServer.h
+++ b/libs/sensor/include/sensor/ISensorServer.h
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_GUI_ISENSORSERVER_H
-#define ANDROID_GUI_ISENSORSERVER_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+#include <utils/Vector.h>
 
 #include <binder/IInterface.h>
 
@@ -30,9 +30,11 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
-class Sensor;
 class ISensorEventConnection;
+class Parcel;
+class Sensor;
 class String8;
+class String16;
 
 class ISensorServer : public IInterface
 {
@@ -63,5 +65,3 @@
 
 // ----------------------------------------------------------------------------
 }; // namespace android
-
-#endif // ANDROID_GUI_ISENSORSERVER_H
diff --git a/include/gui/Sensor.h b/libs/sensor/include/sensor/Sensor.h
similarity index 97%
rename from include/gui/Sensor.h
rename to libs/sensor/include/sensor/Sensor.h
index d886b2b..043e635 100644
--- a/include/gui/Sensor.h
+++ b/libs/sensor/include/sensor/Sensor.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_GUI_SENSOR_H
-#define ANDROID_GUI_SENSOR_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -25,10 +24,11 @@
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
-#include <hardware/sensors.h>
-
+// FIXME: including from android/ breaks layering, as libandroid ultimately depends on libsensors
 #include <android/sensor.h>
 
+#include <hardware/sensors.h>
+
 // ----------------------------------------------------------------------------
 // Concrete types for the NDK
 struct ASensor { };
@@ -138,5 +138,3 @@
 
 // ----------------------------------------------------------------------------
 }; // namespace android
-
-#endif // ANDROID_GUI_SENSOR_H
diff --git a/include/gui/SensorEventQueue.h b/libs/sensor/include/sensor/SensorEventQueue.h
similarity index 94%
rename from include/gui/SensorEventQueue.h
rename to libs/sensor/include/sensor/SensorEventQueue.h
index 4ee7c02..84b6ab2 100644
--- a/include/gui/SensorEventQueue.h
+++ b/libs/sensor/include/sensor/SensorEventQueue.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SENSOR_EVENT_QUEUE_H
-#define ANDROID_SENSOR_EVENT_QUEUE_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -23,9 +22,9 @@
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
-#include <utils/String16.h>
+#include <utils/Mutex.h>
 
-#include <gui/BitTube.h>
+#include <sensor/BitTube.h>
 
 // ----------------------------------------------------------------------------
 #define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31)
@@ -107,5 +106,3 @@
 
 // ----------------------------------------------------------------------------
 }; // namespace android
-
-#endif // ANDROID_SENSOR_EVENT_QUEUE_H
diff --git a/include/gui/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
similarity index 94%
rename from include/gui/SensorManager.h
rename to libs/sensor/include/sensor/SensorManager.h
index 5b34ff4..a3d9741 100644
--- a/include/gui/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -18,6 +18,7 @@
 #define ANDROID_GUI_SENSOR_MANAGER_H
 
 #include <map>
+#include <unordered_map>
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -27,14 +28,11 @@
 #include <binder/IServiceManager.h>
 
 #include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Singleton.h>
+#include <utils/StrongPointer.h>
 #include <utils/Vector.h>
 #include <utils/String8.h>
 
-#include <gui/SensorEventQueue.h>
-
-#include <unordered_map>
+#include <sensor/SensorEventQueue.h>
 
 // ----------------------------------------------------------------------------
 // Concrete types for the NDK
@@ -52,8 +50,7 @@
 class SensorEventQueue;
 // ----------------------------------------------------------------------------
 
-class SensorManager :
-    public ASensorManager
+class SensorManager : public ASensorManager
 {
 public:
     static SensorManager& getInstanceForPackage(const String16& packageName);
diff --git a/libs/sensor/tests/Android.bp b/libs/sensor/tests/Android.bp
new file mode 100644
index 0000000..9d530fc
--- /dev/null
+++ b/libs/sensor/tests/Android.bp
@@ -0,0 +1,29 @@
+// Copyright 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+    name: "libsensor_test",
+
+    clang: true,
+
+    srcs: [
+        "Sensor_test.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libsensor",
+        "libutils",
+    ],
+}
diff --git a/libs/gui/tests/Sensor_test.cpp b/libs/sensor/tests/Sensor_test.cpp
similarity index 98%
rename from libs/gui/tests/Sensor_test.cpp
rename to libs/sensor/tests/Sensor_test.cpp
index fbf282d..ede20c9 100644
--- a/libs/gui/tests/Sensor_test.cpp
+++ b/libs/sensor/tests/Sensor_test.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "Sensor_test"
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 #include <hardware/sensors.h>
 #include <utils/Errors.h>
 
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index c4d8f76..9006178 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -16,6 +16,8 @@
 
 #define LOG_TAG "GraphicBuffer"
 
+#include <cutils/atomic.h>
+
 #include <ui/GraphicBuffer.h>
 
 #include <cutils/atomic.h>
diff --git a/libs/vr/libposepredictor/predictor.cpp b/libs/vr/libposepredictor/predictor.cpp
index 266e7ef..4d2eafd 100644
--- a/libs/vr/libposepredictor/predictor.cpp
+++ b/libs/vr/libposepredictor/predictor.cpp
@@ -8,7 +8,7 @@
   const auto delta_q = b.inverse() * a;
   // Check that delta_q.w() == 1, Eigen doesn't respect this convention. If
   // delta_q.w() == -1, we'll get the opposite velocity.
-  return 2.0 * (delta_q.w() < 0 ? -delta_q.vec() : delta_q.vec()) / delta_time;
+  return 2.0 * (delta_q.w() < 0 ? static_cast<vec3>(-delta_q.vec()) : delta_q.vec()) / delta_time;
 }
 
 Velocity Predictor::PredictVelocity(int64_t time_ns) const {
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 0ac74db..740ead3 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -623,9 +623,9 @@
 #define EGL_ANDROID_get_native_client_buffer 1
 struct AHardwareBuffer;
 #ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLClientBuffer eglGetNativeClientBufferANDROID (const AHardwareBuffer *buffer);
+EGLAPI EGLClientBuffer eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer);
 #else
-typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const AHardwareBuffer *buffer);
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const struct AHardwareBuffer *buffer);
 #endif
 #endif
 
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/sensorservice/Android.mk b/services/sensorservice/Android.mk
index d61f26f..cfb7231 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -33,8 +33,7 @@
     libutils \
     liblog \
     libbinder \
-    libui \
-    libgui \
+    libsensor \
     libcrypto \
     libbase \
     libhidlbase \
@@ -45,6 +44,10 @@
 LOCAL_STATIC_LIBRARIES := \
     android.hardware.sensors@1.0-convert
 
+# our public headers depend on libsensor
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+    libsensor \
+
 LOCAL_MODULE:= libsensorservice
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/sensorservice/CorrectedGyroSensor.h b/services/sensorservice/CorrectedGyroSensor.h
index 68acd43..1d49e01 100644
--- a/services/sensorservice/CorrectedGyroSensor.h
+++ b/services/sensorservice/CorrectedGyroSensor.h
@@ -20,7 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 
 #include "SensorInterface.h"
 
diff --git a/services/sensorservice/GravitySensor.h b/services/sensorservice/GravitySensor.h
index 8e33a73..483f468 100644
--- a/services/sensorservice/GravitySensor.h
+++ b/services/sensorservice/GravitySensor.h
@@ -20,7 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 
 #include "SensorInterface.h"
 
diff --git a/services/sensorservice/LinearAccelerationSensor.h b/services/sensorservice/LinearAccelerationSensor.h
index 428baa6..aa4e54a 100644
--- a/services/sensorservice/LinearAccelerationSensor.h
+++ b/services/sensorservice/LinearAccelerationSensor.h
@@ -20,7 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 
 #include "SensorInterface.h"
 #include "GravitySensor.h"
diff --git a/services/sensorservice/OrientationSensor.h b/services/sensorservice/OrientationSensor.h
index 30ff226..a3f2a99 100644
--- a/services/sensorservice/OrientationSensor.h
+++ b/services/sensorservice/OrientationSensor.h
@@ -20,7 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 
 #include "SensorInterface.h"
 
diff --git a/services/sensorservice/RotationVectorSensor.h b/services/sensorservice/RotationVectorSensor.h
index 265b4c4..34deaa9 100644
--- a/services/sensorservice/RotationVectorSensor.h
+++ b/services/sensorservice/RotationVectorSensor.h
@@ -20,7 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 
 #include "SensorDevice.h"
 #include "SensorInterface.h"
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 3edd50b..7bd495f 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -13,21 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <sys/types.h>
+#include "SensorDevice.h"
+#include "SensorService.h"
 
 #include <android-base/logging.h>
+#include <sensors/convert.h>
 #include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/Singleton.h>
 
-#include "SensorDevice.h"
-#include "SensorService.h"
-
-#include <sensors/convert.h>
+#include <chrono>
+#include <cinttypes>
+#include <thread>
 
 using android::hardware::hidl_vec;
 
@@ -55,13 +52,38 @@
 }
 
 SensorDevice::SensorDevice() {
-    mSensors = ISensors::getService();
+    // SensorDevice may wait upto 100ms * 10 = 1s for hidl service.
+    constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
+    size_t retry = 10;
 
-    if (mSensors == NULL) {
-        return;
+    while (true) {
+        int initStep = 0;
+        mSensors = ISensors::getService();
+        if (mSensors != nullptr) {
+            ++initStep;
+            // Poke ISensor service. If it has lingering connection from previous generation of
+            // system server, it will kill itself. There is no intention to handle the poll result,
+            // which will be done since the size is 0.
+            if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
+                // ok to continue
+                break;
+            }
+            // hidl service is restarting, pointer is invalid.
+            mSensors = nullptr;
+        }
+
+        if (--retry <= 0) {
+            ALOGE("Cannot connect to ISensors hidl service!");
+            return;
+        }
+        // Delay 100ms before retry, hidl service is expected to come up in short time after
+        // crash.
+        ALOGI("%s unsuccessful, try again soon (remaining retry %zu).",
+                (initStep == 0) ? "getService()" : "poll() check", retry);
+        std::this_thread::sleep_for(RETRY_DELAY);
     }
 
-    mSensors->getSensorsList(
+    checkReturn(mSensors->getSensorsList(
             [&](const auto &list) {
                 const size_t count = list.size();
 
@@ -74,19 +96,19 @@
 
                     mActivationCount.add(list[i].sensorHandle, model);
 
-                    mSensors->activate(list[i].sensorHandle, 0 /* enabled */);
+                    checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));
                 }
-            });
+            }));
 
     mIsDirectReportSupported =
-           (mSensors->unregisterDirectChannel(-1) != Result::INVALID_OPERATION);
+           (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
 }
 
 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
     if (connected) {
         Info model;
         mActivationCount.add(handle, model);
-        mSensors->activate(handle, 0 /* enabled */);
+        checkReturn(mSensors->activate(handle, 0 /* enabled */));
     } else {
         mActivationCount.removeItem(handle);
     }
@@ -96,7 +118,7 @@
     if (mSensors == NULL) return "HAL not initialized\n";
 
     String8 result;
-    mSensors->getSensorsList([&](const auto &list) {
+    checkReturn(mSensors->getSensorsList([&](const auto &list) {
             const size_t count = list.size();
 
             result.appendFormat(
@@ -141,7 +163,7 @@
                         "}, selected = %.1f ms\n",
                         info.bestBatchParams.batchTimeout / 1e6f);
             }
-        });
+        }));
 
     return result.string();
 }
@@ -161,7 +183,7 @@
 
     ssize_t err;
 
-    mSensors->poll(
+    checkReturn(mSensors->poll(
             count,
             [&](auto result,
                 const auto &events,
@@ -172,7 +194,7 @@
                 } else {
                     err = StatusFromResult(result);
                 }
-            });
+            }));
 
     return err;
 }
@@ -237,10 +259,10 @@
                          "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
                          info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
                          info.bestBatchParams.batchTimeout);
-                mSensors->batch(
+                checkReturn(mSensors->batch(
                         handle,
                         info.bestBatchParams.batchDelay,
-                        info.bestBatchParams.batchTimeout);
+                        info.bestBatchParams.batchTimeout));
             }
         } else {
             // sensor wasn't enabled for this ident
@@ -254,7 +276,7 @@
     if (actuateHardware) {
         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
                  enabled);
-        err = StatusFromResult(mSensors->activate(handle, enabled));
+        err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
                  strerror(-err));
 
@@ -311,10 +333,10 @@
                  info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
                  info.bestBatchParams.batchTimeout);
         err = StatusFromResult(
-                mSensors->batch(
+                checkReturn(mSensors->batch(
                     handle,
                     info.bestBatchParams.batchDelay,
-                    info.bestBatchParams.batchTimeout));
+                    info.bestBatchParams.batchTimeout)));
         if (err != NO_ERROR) {
             ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
                   mSensors.get(), handle,
@@ -348,7 +370,7 @@
     info.selectBatchParams();
 
     return StatusFromResult(
-            mSensors->batch(handle, info.bestBatchParams.batchDelay, 0));
+            checkReturn(mSensors->batch(handle, info.bestBatchParams.batchDelay, 0)));
 }
 
 int SensorDevice::getHalDeviceVersion() const {
@@ -359,7 +381,7 @@
 status_t SensorDevice::flush(void* ident, int handle) {
     if (isClientDisabled(ident)) return INVALID_OPERATION;
     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
-    return StatusFromResult(mSensors->flush(handle));
+    return StatusFromResult(checkReturn(mSensors->flush(handle)));
 }
 
 bool SensorDevice::isClientDisabled(void* ident) {
@@ -383,15 +405,15 @@
         ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
                    sensor_handle);
         status_t err = StatusFromResult(
-                mSensors->batch(
+                checkReturn(mSensors->batch(
                     sensor_handle,
                     info.bestBatchParams.batchDelay,
-                    info.bestBatchParams.batchTimeout));
+                    info.bestBatchParams.batchTimeout)));
         ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
 
         if (err == NO_ERROR) {
             err = StatusFromResult(
-                    mSensors->activate(sensor_handle, 1 /* enabled */));
+                    checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
             ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
         }
     }
@@ -406,7 +428,7 @@
            const int sensor_handle = mActivationCount.keyAt(i);
            ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
                    sensor_handle);
-           mSensors->activate(sensor_handle, 0 /* enabled */);
+           checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
 
            // Add all the connections that were registered for this sensor to the disabled
            // clients list.
@@ -431,14 +453,14 @@
     Event ev;
     convertFromSensorEvent(*injected_sensor_event, &ev);
 
-    return StatusFromResult(mSensors->injectSensorData(ev));
+    return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
 }
 
 status_t SensorDevice::setMode(uint32_t mode) {
 
      return StatusFromResult(
-             mSensors->setOperationMode(
-                 static_cast<hardware::sensors::V1_0::OperationMode>(mode)));
+             checkReturn(mSensors->setOperationMode(
+                 static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
 }
 
 // ---------------------------------------------------------------------------
@@ -529,20 +551,20 @@
     };
 
     int32_t ret;
-    mSensors->registerDirectChannel(mem,
+    checkReturn(mSensors->registerDirectChannel(mem,
             [&ret](auto result, auto channelHandle) {
                 if (result == Result::OK) {
                     ret = channelHandle;
                 } else {
                     ret = StatusFromResult(result);
                 }
-            });
+            }));
     return ret;
 }
 
 void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
     Mutex::Autolock _l(mLock);
-    mSensors->unregisterDirectChannel(channelHandle);
+    checkReturn(mSensors->unregisterDirectChannel(channelHandle));
 }
 
 int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
@@ -568,7 +590,7 @@
     }
 
     int32_t ret;
-    mSensors->configDirectReport(sensorHandle, channelHandle, rate,
+    checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
             [&ret, rate] (auto result, auto token) {
                 if (rate == RateLevel::STOP) {
                     ret = StatusFromResult(result);
@@ -579,7 +601,7 @@
                         ret = StatusFromResult(result);
                     }
                 }
-            });
+            }));
 
     return ret;
 }
@@ -635,5 +657,10 @@
     }
 }
 
+void SensorDevice::handleHidlDeath(const std::string & detail) {
+    // restart is the only option at present.
+    LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 7f95429..03552f6 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -19,7 +19,7 @@
 
 #include "SensorServiceUtils.h"
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/KeyedVector.h>
@@ -37,6 +37,7 @@
 
 // ---------------------------------------------------------------------------
 using SensorServiceUtil::Dumpable;
+using hardware::Return;
 
 class SensorDevice : public Singleton<SensorDevice>, public Dumpable {
 public:
@@ -128,6 +129,15 @@
     SortedVector<void *> mDisabledClients;
     SensorDevice();
 
+    static void handleHidlDeath(const std::string &detail);
+    template<typename T>
+    static Return<T> checkReturn(Return<T> &&ret) {
+        if (!ret.isOk()) {
+            handleHidlDeath(ret.description());
+        }
+        return std::move(ret);
+    }
+
     bool isClientDisabled(void* ident);
     bool isClientDisabledLocked(void* ident);
 
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index 692ef0d..27458d4 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -22,10 +22,10 @@
 
 #include <binder/BinderService.h>
 
-#include <gui/Sensor.h>
-#include <gui/BitTube.h>
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/BitTube.h>
+#include <sensor/ISensorServer.h>
+#include <sensor/ISensorEventConnection.h>
 
 #include "SensorService.h"
 
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index d84d36e..fad046c 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -17,7 +17,7 @@
 #include <sys/socket.h>
 #include <utils/threads.h>
 
-#include <gui/SensorEventQueue.h>
+#include <sensor/SensorEventQueue.h>
 
 #include "vec.h"
 #include "SensorEventConnection.h"
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index cd81ddd..c81e015 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -31,10 +31,10 @@
 
 #include <binder/BinderService.h>
 
-#include <gui/Sensor.h>
-#include <gui/BitTube.h>
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/BitTube.h>
+#include <sensor/ISensorServer.h>
+#include <sensor/ISensorEventConnection.h>
 
 #include "SensorService.h"
 
diff --git a/services/sensorservice/SensorFusion.h b/services/sensorservice/SensorFusion.h
index ad636d5..8c0fbf9 100644
--- a/services/sensorservice/SensorFusion.h
+++ b/services/sensorservice/SensorFusion.h
@@ -24,7 +24,7 @@
 #include <utils/Singleton.h>
 #include <utils/String8.h>
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 
 #include "Fusion.h"
 
diff --git a/services/sensorservice/SensorInterface.h b/services/sensorservice/SensorInterface.h
index 0867dc2..b5375cb 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_SENSOR_INTERFACE_H
 #define ANDROID_SENSOR_INTERFACE_H
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 #include <utils/RefBase.h>
 
 // ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorList.h b/services/sensorservice/SensorList.h
index 8209d96..6b90ad9 100644
--- a/services/sensorservice/SensorList.h
+++ b/services/sensorservice/SensorList.h
@@ -20,7 +20,7 @@
 #include "SensorInterface.h"
 #include "SensorServiceUtils.h"
 
-#include <gui/Sensor.h>
+#include <sensor/Sensor.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 143a3c5..c11df13 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -22,7 +22,7 @@
 #include <binder/PermissionCache.h>
 
 #include <cutils/ashmem.h>
-#include <gui/SensorEventQueue.h>
+#include <sensor/SensorEventQueue.h>
 
 #include <hardware/sensors.h>
 #include <hardware_legacy/power.h>
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index eeedd4a..5583dad 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -22,9 +22,9 @@
 
 #include <binder/BinderService.h>
 #include <cutils/compiler.h>
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
-#include <gui/Sensor.h>
+#include <sensor/ISensorServer.h>
+#include <sensor/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
 
 #include <utils/AndroidThreads.h>
 #include <utils/KeyedVector.h>
diff --git a/services/sensorservice/tests/Android.mk b/services/sensorservice/tests/Android.mk
index 45296dd..e894655 100644
--- a/services/sensorservice/tests/Android.mk
+++ b/services/sensorservice/tests/Android.mk
@@ -5,7 +5,7 @@
 	sensorservicetest.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-	libcutils libutils libui libgui
+	libutils libsensor libandroid
 
 LOCAL_MODULE:= test-sensorservice
 
diff --git a/services/sensorservice/tests/sensorservicetest.cpp b/services/sensorservice/tests/sensorservicetest.cpp
index 186b60c..1cb0489 100644
--- a/services/sensorservice/tests/sensorservicetest.cpp
+++ b/services/sensorservice/tests/sensorservicetest.cpp
@@ -16,9 +16,9 @@
 
 #include <inttypes.h>
 #include <android/sensor.h>
-#include <gui/Sensor.h>
-#include <gui/SensorManager.h>
-#include <gui/SensorEventQueue.h>
+#include <sensor/Sensor.h>
+#include <sensor/SensorManager.h>
+#include <sensor/SensorEventQueue.h>
 #include <utils/Looper.h>
 
 using namespace android;
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 92ede08..caa7adc 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -242,7 +242,11 @@
     static status_t orientationToTransfrom(int orientation,
             int w, int h, Transform* tr);
 
+    // The identifier of the active layer stack for this display. Several displays
+    // can use the same layer stack: A z-ordered group of layers (sometimes called
+    // "surfaces"). Any given layer can only be on a single layer stack.
     uint32_t mLayerStack;
+
     int mOrientation;
     static uint32_t sPrimaryDisplayOrientation;
     // user-provided visible area of the layer stack
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index d1bc7eb..486bce4 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -21,7 +21,7 @@
 
 #include <cutils/compiler.h>
 
-#include <gui/BitTube.h>
+#include <private/gui/BitTube.h>
 #include <gui/IDisplayEventConnection.h>
 #include <gui/DisplayEventReceiver.h>
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f2e5f22..e2b2a3a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -109,7 +109,14 @@
         Geometry active;
         Geometry requested;
         int32_t z;
+
+        // The identifier of the layer stack this layer belongs to. A layer can
+        // only be associated to a single layer stack. A layer stack is a
+        // z-ordered group of layers which can be associated to one or more
+        // displays. Using the same layer stack on different displays is a way
+        // to achieve mirroring.
         uint32_t layerStack;
+
 #ifdef USE_HWC2
         float alpha;
 #else
@@ -697,6 +704,11 @@
         Rect displayFrame;
         FloatRect sourceCrop;
     };
+
+    // A layer can be attached to multiple displays when operating in mirror mode
+    // (a.k.a: when several displays are attached with equal layerStack). In this
+    // case we need to keep track. In non-mirror mode, a layer will have only one.
+    // HWCInfo. This map key is a display layerStack.
     std::unordered_map<int32_t, HWCInfo> mHwcLayers;
 
     // We need one HWComposerBufferCache for each HWC display.  We cannot have
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index 974c7a3..debea58 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -25,7 +25,7 @@
 #include <utils/Log.h>
 
 #include <gui/IDisplayEventConnection.h>
-#include <gui/BitTube.h>
+#include <private/gui/BitTube.h>
 
 #include "MessageQueue.h"
 #include "EventThread.h"
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2f354bb..46f5a1f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -40,7 +40,6 @@
 #include <ui/DisplayInfo.h>
 #include <ui/DisplayStatInfo.h>
 
-#include <gui/BitTube.h>
 #include <gui/BufferQueue.h>
 #include <gui/GuiConfig.h>
 #include <gui/IDisplayEventConnection.h>
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index fe8dd0c..6cd7152 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -38,7 +38,6 @@
 #include <ui/DisplayInfo.h>
 #include <ui/DisplayStatInfo.h>
 
-#include <gui/BitTube.h>
 #include <gui/BufferQueue.h>
 #include <gui/GuiConfig.h>
 #include <gui/IDisplayEventConnection.h>
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/driver.cpp b/vulkan/libvulkan/driver.cpp
index 351caeb..b62eec6 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -778,9 +778,6 @@
     loader_extensions.push_back({
         VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
         VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
-    loader_extensions.push_back({
-        VK_EXT_HDR_METADATA_EXTENSION_NAME,
-        VK_EXT_HDR_METADATA_SPEC_VERSION});
 
     // conditionally add shared_presentable_image if supportable
     VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
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;