Merge changes I2f531131,Ibaaca2a1,Ib0cba4c7,I5ea748b8,I046e3f07, ... into oc-dev

* changes:
  libgui: Make IDisplayEventConn... a SafeInterface
  libgui: Remove RefBase from BitTube
  libgui: Make BitTube Parcelable and use unique_fd
  libgui: Format BitTube and move into gui namespace
  libgui: Move BitTube out of system include dir
  libgui: Normalize IDisplayEventConnection methods
  libgui: Format IDisplayEventConnection
diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h
index cb9b373..9557b4f 100644
--- a/include/gui/DisplayEventReceiver.h
+++ b/include/gui/DisplayEventReceiver.h
@@ -32,9 +32,12 @@
 
 // ----------------------------------------------------------------------------
 
-class BitTube;
 class IDisplayEventConnection;
 
+namespace gui {
+class BitTube;
+} // namespace gui
+
 static inline constexpr uint32_t fourcc(char c1, char c2, char c3, char c4) {
     return static_cast<uint32_t>(c1) << 24 |
         static_cast<uint32_t>(c2) << 16 |
@@ -108,15 +111,13 @@
      * should be destroyed and getEvents() shouldn't be called again.
      */
     ssize_t getEvents(Event* events, size_t count);
-    static ssize_t getEvents(const sp<BitTube>& dataChannel,
-            Event* events, size_t count);
+    static ssize_t getEvents(gui::BitTube* dataChannel, Event* events, size_t count);
 
     /*
      * sendEvents write events to the queue and returns how many events were
      * written.
      */
-    static ssize_t sendEvents(const sp<BitTube>& dataChannel,
-            Event const* events, size_t count);
+    static ssize_t sendEvents(gui::BitTube* dataChannel, Event const* events, size_t count);
 
     /*
      * setVsyncRate() sets the Event::VSync delivery rate. A value of
@@ -134,7 +135,7 @@
 
 private:
     sp<IDisplayEventConnection> mEventConnection;
-    sp<BitTube> mDataChannel;
+    std::unique_ptr<gui::BitTube> mDataChannel;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/IDisplayEventConnection.h b/include/gui/IDisplayEventConnection.h
index 848368c..d783f74 100644
--- a/include/gui/IDisplayEventConnection.h
+++ b/include/gui/IDisplayEventConnection.h
@@ -14,60 +14,52 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H
-#define ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
+#pragma once
 
 #include <binder/IInterface.h>
+#include <binder/SafeInterface.h>
+
+#include <utils/Errors.h>
+
+#include <cstdint>
 
 namespace android {
-// ----------------------------------------------------------------------------
 
+namespace gui {
 class BitTube;
+} // namespace gui
 
-class IDisplayEventConnection : public IInterface
-{
+class IDisplayEventConnection : public IInterface {
 public:
-
     DECLARE_META_INTERFACE(DisplayEventConnection)
 
     /*
-     * getDataChannel() returns a BitTube where to receive the events from
+     * stealReceiveChannel() returns a BitTube to receive events from. Only the receive file
+     * descriptor of outChannel will be initialized, and this effectively "steals" the receive
+     * channel from the remote end (such that the remote end can only use its send channel).
      */
-    virtual sp<BitTube> getDataChannel() const = 0;
+    virtual status_t stealReceiveChannel(gui::BitTube* outChannel) = 0;
 
     /*
-     * setVsyncRate() sets the vsync event delivery rate. A value of
-     * 1 returns every vsync events. A value of 2 returns every other events,
-     * etc... a value of 0 returns no event unless  requestNextVsync() has
-     * been called.
+     * setVsyncRate() sets the vsync event delivery rate. A value of 1 returns every vsync event.
+     * A value of 2 returns every other event, etc. A value of 0 returns no event unless
+     * requestNextVsync() has been called.
      */
-    virtual void setVsyncRate(uint32_t count) = 0;
+    virtual status_t setVsyncRate(uint32_t count) = 0;
 
     /*
-     * requestNextVsync() schedules the next vsync event. It has no effect
-     * if the vsync rate is > 0.
+     * requestNextVsync() schedules the next vsync event. It has no effect if the vsync rate is > 0.
      */
-    virtual void requestNextVsync() = 0;    // asynchronous
+    virtual void requestNextVsync() = 0; // Asynchronous
 };
 
-// ----------------------------------------------------------------------------
-
-class BnDisplayEventConnection : public BnInterface<IDisplayEventConnection>
-{
+class BnDisplayEventConnection : public SafeBnInterface<IDisplayEventConnection> {
 public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
+    BnDisplayEventConnection()
+          : SafeBnInterface<IDisplayEventConnection>("BnDisplayEventConnection") {}
+
+    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                        uint32_t flags = 0) override;
 };
 
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H
+} // namespace android
diff --git a/include/private/gui/BitTube.h b/include/private/gui/BitTube.h
deleted file mode 100644
index 9d65fad..0000000
--- a/include/private/gui/BitTube.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_GUI_SENSOR_CHANNEL_H
-#define ANDROID_GUI_SENSOR_CHANNEL_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <android/log.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
-
-#endif // ANDROID_GUI_SENSOR_CHANNEL_H
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 28c2a48..90ab286 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -126,6 +126,10 @@
         "android.hidl.token@1.0-utils",
         "android.hardware.graphics.bufferqueue@1.0",
     ],
+
+    export_include_dirs: [
+        "include",
+    ],
 }
 
 subdirs = ["tests"]
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index 51a8d67..ef7a6f5 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -17,8 +17,8 @@
 #include <private/gui/BitTube.h>
 
 #include <stdint.h>
-#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 
 #include <fcntl.h>
 #include <unistd.h>
@@ -27,45 +27,21 @@
 
 #include <binder/Parcel.h>
 
-
 namespace android {
-// ----------------------------------------------------------------------------
+namespace gui {
 
-// Socket buffer size.  The default is typically about 128KB, which is much larger than
-// we really need.  So we make it smaller.
+// 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)
-{
+BitTube::BitTube(size_t bufsize) {
     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(DefaultSizeType) : BitTube(DEFAULT_SOCKET_BUFFER_SIZE) {}
 
-BitTube::~BitTube()
-{
-    if (mSendFd >= 0)
-        close(mSendFd);
-
-    if (mReceiveFd >= 0)
-        close(mReceiveFd);
+BitTube::BitTube(const Parcel& data) {
+    readFromParcel(&data);
 }
 
 void BitTube::init(size_t rcvbuf, size_t sndbuf) {
@@ -74,39 +50,43 @@
         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...
+        // since 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];
+        mReceiveFd.reset(sockets[0]);
+        mSendFd.reset(sockets[1]);
     } else {
-        mReceiveFd = -errno;
-        ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
+        mReceiveFd.reset();
+        ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));
     }
 }
 
-status_t BitTube::initCheck() const
-{
+status_t BitTube::initCheck() const {
     if (mReceiveFd < 0) {
         return status_t(mReceiveFd);
     }
     return NO_ERROR;
 }
 
-int BitTube::getFd() const
-{
+int BitTube::getFd() const {
     return mReceiveFd;
 }
 
-int BitTube::getSendFd() const
-{
+int BitTube::getSendFd() const {
     return mSendFd;
 }
 
-ssize_t BitTube::write(void const* vaddr, size_t size)
-{
+base::unique_fd BitTube::moveReceiveFd() {
+    return std::move(mReceiveFd);
+}
+
+void BitTube::setReceiveFd(base::unique_fd&& receiveFd) {
+    mReceiveFd = std::move(receiveFd);
+}
+
+ssize_t BitTube::write(void const* vaddr, size_t size) {
     ssize_t err, len;
     do {
         len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
@@ -116,62 +96,66 @@
     return err == 0 ? len : -err;
 }
 
-ssize_t BitTube::read(void* vaddr, size_t size)
-{
+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.
+        // 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 BitTube::writeToParcel(Parcel* reply) const {
+    if (mReceiveFd < 0) return -EINVAL;
 
     status_t result = reply->writeDupFileDescriptor(mReceiveFd);
-    close(mReceiveFd);
-    mReceiveFd = -1;
+    mReceiveFd.reset();
     return result;
 }
 
+status_t BitTube::readFromParcel(const Parcel* parcel) {
+    mReceiveFd.reset(dup(parcel->readFileDescriptor()));
+    if (mReceiveFd < 0) {
+        mReceiveFd.reset();
+        int error = errno;
+        ALOGE("BitTube::readFromParcel: can't dup file descriptor (%s)", strerror(error));
+        return -error;
+    }
+    return NO_ERROR;
+}
 
-ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
-        void const* events, size_t count, size_t objSize)
-{
+ssize_t BitTube::sendObjects(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);
+    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);
+                        "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);
+    // 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)
-{
+ssize_t BitTube::recvObjects(BitTube* tube, void* events, size_t count, size_t objSize) {
     char* vaddr = reinterpret_cast<char*>(events);
-    ssize_t size = tube->read(vaddr, count*objSize);
+    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);
+                        "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);
+    // ALOGE_IF(size<0, "error %d receiving %d events", size, count);
     return size < 0 ? size : size / static_cast<ssize_t>(objSize);
 }
 
-// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace gui
+} // namespace android
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index 07e07e0..1507d51 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -37,7 +37,8 @@
     if (sf != NULL) {
         mEventConnection = sf->createDisplayEventConnection();
         if (mEventConnection != NULL) {
-            mDataChannel = mEventConnection->getDataChannel();
+            mDataChannel = std::make_unique<gui::BitTube>();
+            mEventConnection->stealReceiveChannel(mDataChannel.get());
         }
     }
 }
@@ -80,19 +81,19 @@
 
 ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
         size_t count) {
-    return DisplayEventReceiver::getEvents(mDataChannel, events, count);
+    return DisplayEventReceiver::getEvents(mDataChannel.get(), events, count);
 }
 
-ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel,
+ssize_t DisplayEventReceiver::getEvents(gui::BitTube* dataChannel,
         Event* events, size_t count)
 {
-    return BitTube::recvObjects(dataChannel, events, count);
+    return gui::BitTube::recvObjects(dataChannel, events, count);
 }
 
-ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel,
+ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
         Event const* events, size_t count)
 {
-    return BitTube::sendObjects(dataChannel, events, count);
+    return gui::BitTube::sendObjects(dataChannel, events, count);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
index e5c3c48..c0e246f 100644
--- a/libs/gui/IDisplayEventConnection.cpp
+++ b/libs/gui/IDisplayEventConnection.cpp
@@ -14,89 +14,67 @@
  * limitations under the License.
  */
 
-#include <stdint.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include <binder/Parcel.h>
-
 #include <gui/IDisplayEventConnection.h>
 
 #include <private/gui/BitTube.h>
 
 namespace android {
-// ----------------------------------------------------------------------------
 
-enum {
-    GET_DATA_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
+namespace { // Anonymous
+
+enum class Tag : uint32_t {
+    STEAL_RECEIVE_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
     SET_VSYNC_RATE,
-    REQUEST_NEXT_VSYNC
+    REQUEST_NEXT_VSYNC,
+    LAST = REQUEST_NEXT_VSYNC,
 };
 
-class BpDisplayEventConnection : public BpInterface<IDisplayEventConnection>
-{
+} // Anonymous namespace
+
+class BpDisplayEventConnection : public SafeBpInterface<IDisplayEventConnection> {
 public:
     explicit BpDisplayEventConnection(const sp<IBinder>& impl)
-        : BpInterface<IDisplayEventConnection>(impl)
-    {
+          : SafeBpInterface<IDisplayEventConnection>(impl, "BpDisplayEventConnection") {}
+
+    ~BpDisplayEventConnection() override;
+
+    status_t stealReceiveChannel(gui::BitTube* outChannel) override {
+        return callRemote<decltype(
+                &IDisplayEventConnection::stealReceiveChannel)>(Tag::STEAL_RECEIVE_CHANNEL,
+                                                                outChannel);
     }
 
-    virtual ~BpDisplayEventConnection();
-
-    virtual sp<BitTube> getDataChannel() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
-        remote()->transact(GET_DATA_CHANNEL, data, &reply);
-        return new BitTube(reply);
+    status_t setVsyncRate(uint32_t count) override {
+        return callRemote<decltype(&IDisplayEventConnection::setVsyncRate)>(Tag::SET_VSYNC_RATE,
+                                                                            count);
     }
 
-    virtual void setVsyncRate(uint32_t count) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
-        data.writeUint32(count);
-        remote()->transact(SET_VSYNC_RATE, data, &reply);
-    }
-
-    virtual void requestNextVsync() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
-        remote()->transact(REQUEST_NEXT_VSYNC, data, &reply, IBinder::FLAG_ONEWAY);
+    void requestNextVsync() override {
+        callRemoteAsync<decltype(&IDisplayEventConnection::requestNextVsync)>(
+                Tag::REQUEST_NEXT_VSYNC);
     }
 };
 
-// Out-of-line virtual method definition to trigger vtable emission in this
-// translation unit (see clang warning -Wweak-vtables)
-BpDisplayEventConnection::~BpDisplayEventConnection() {}
+// Out-of-line virtual method definition to trigger vtable emission in this translation unit (see
+// clang warning -Wweak-vtables)
+BpDisplayEventConnection::~BpDisplayEventConnection() = default;
 
 IMPLEMENT_META_INTERFACE(DisplayEventConnection, "android.gui.DisplayEventConnection");
 
-// ----------------------------------------------------------------------------
-
-status_t BnDisplayEventConnection::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case GET_DATA_CHANNEL: {
-            CHECK_INTERFACE(IDisplayEventConnection, data, reply);
-            sp<BitTube> channel(getDataChannel());
-            channel->writeToParcel(reply);
-            return NO_ERROR;
-        }
-        case SET_VSYNC_RATE: {
-            CHECK_INTERFACE(IDisplayEventConnection, data, reply);
-            setVsyncRate(data.readUint32());
-            return NO_ERROR;
-        }
-        case REQUEST_NEXT_VSYNC: {
-            CHECK_INTERFACE(IDisplayEventConnection, data, reply);
-            requestNextVsync();
-            return NO_ERROR;
-        }
+status_t BnDisplayEventConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                                              uint32_t flags) {
+    if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
+        return BBinder::onTransact(code, data, reply, flags);
     }
-    return BBinder::onTransact(code, data, reply, flags);
+    auto tag = static_cast<Tag>(code);
+    switch (tag) {
+        case Tag::STEAL_RECEIVE_CHANNEL:
+            return callLocal(data, reply, &IDisplayEventConnection::stealReceiveChannel);
+        case Tag::SET_VSYNC_RATE:
+            return callLocal(data, reply, &IDisplayEventConnection::setVsyncRate);
+        case Tag::REQUEST_NEXT_VSYNC:
+            return callLocalAsync(data, reply, &IDisplayEventConnection::requestNextVsync);
+    }
 }
 
-// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/libs/gui/include/private/gui/BitTube.h b/libs/gui/include/private/gui/BitTube.h
new file mode 100644
index 0000000..13c0162
--- /dev/null
+++ b/libs/gui/include/private/gui/BitTube.h
@@ -0,0 +1,97 @@
+/*
+ * 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 <android-base/unique_fd.h>
+#include <binder/Parcelable.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+class Parcel;
+
+namespace gui {
+
+class BitTube : public Parcelable {
+public:
+    // creates an uninitialized BitTube (to unparcel into)
+    BitTube() = default;
+
+    // creates a BitTube with a a specified send and receive buffer size
+    explicit BitTube(size_t bufsize);
+
+    // creates a BitTube with a default (4KB) send buffer
+    struct DefaultSizeType {};
+    static constexpr DefaultSizeType DefaultSize{};
+    explicit BitTube(DefaultSizeType);
+
+    explicit BitTube(const Parcel& data);
+
+    virtual ~BitTube() = default;
+
+    // check state after construction
+    status_t initCheck() const;
+
+    // get receive file-descriptor
+    int getFd() const;
+
+    // get the send file-descriptor.
+    int getSendFd() const;
+
+    // moves the receive file descriptor out of this BitTube
+    base::unique_fd moveReceiveFd();
+
+    // resets this BitTube's receive file descriptor to receiveFd
+    void setReceiveFd(base::unique_fd&& receiveFd);
+
+    // send objects (sized blobs). All objects are guaranteed to be written or the call fails.
+    template <typename T>
+    static ssize_t sendObjects(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(BitTube* tube, T* events, size_t count) {
+        return recvObjects(tube, events, count, sizeof(T));
+    }
+
+    // implement the Parcelable protocol. Only parcels the receive file descriptor
+    status_t writeToParcel(Parcel* reply) const;
+    status_t readFromParcel(const Parcel* parcel);
+
+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);
+
+    base::unique_fd mSendFd;
+    mutable base::unique_fd mReceiveFd;
+
+    static ssize_t sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize);
+
+    static ssize_t recvObjects(BitTube* tube, void* events, size_t count, size_t objSize);
+};
+
+} // namespace gui
+} // namespace android
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 486bce4..a9bb2ba 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -21,7 +21,6 @@
 
 #include <cutils/compiler.h>
 
-#include <private/gui/BitTube.h>
 #include <gui/IDisplayEventConnection.h>
 #include <gui/DisplayEventReceiver.h>
 
@@ -389,7 +388,7 @@
 
 EventThread::Connection::Connection(
         const sp<EventThread>& eventThread)
-    : count(-1), mEventThread(eventThread), mChannel(new BitTube())
+    : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize)
 {
 }
 
@@ -403,12 +402,14 @@
     mEventThread->registerDisplayEventConnection(this);
 }
 
-sp<BitTube> EventThread::Connection::getDataChannel() const {
-    return mChannel;
+status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
+    outChannel->setReceiveFd(mChannel.moveReceiveFd());
+    return NO_ERROR;
 }
 
-void EventThread::Connection::setVsyncRate(uint32_t count) {
+status_t EventThread::Connection::setVsyncRate(uint32_t count) {
     mEventThread->setVsyncRate(count, this);
+    return NO_ERROR;
 }
 
 void EventThread::Connection::requestNextVsync() {
@@ -417,7 +418,7 @@
 
 status_t EventThread::Connection::postEvent(
         const DisplayEventReceiver::Event& event) {
-    ssize_t size = DisplayEventReceiver::sendEvents(mChannel, &event, 1);
+    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
     return size < 0 ? status_t(size) : status_t(NO_ERROR);
 }
 
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index 3f1d0bb..6a59fbb 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <private/gui/BitTube.h>
 #include <gui/DisplayEventReceiver.h>
 #include <gui/IDisplayEventConnection.h>
 
@@ -68,11 +69,11 @@
     private:
         virtual ~Connection();
         virtual void onFirstRef();
-        virtual sp<BitTube> getDataChannel() const;
-        virtual void setVsyncRate(uint32_t count);
-        virtual void requestNextVsync();    // asynchronous
+        status_t stealReceiveChannel(gui::BitTube* outChannel) override;
+        status_t setVsyncRate(uint32_t count) override;
+        void requestNextVsync() override;    // asynchronous
         sp<EventThread> const mEventThread;
-        sp<BitTube> const mChannel;
+        gui::BitTube mChannel;
     };
 
 public:
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index debea58..bca3430 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -25,7 +25,6 @@
 #include <utils/Log.h>
 
 #include <gui/IDisplayEventConnection.h>
-#include <private/gui/BitTube.h>
 
 #include "MessageQueue.h"
 #include "EventThread.h"
@@ -94,8 +93,8 @@
 {
     mEventThread = eventThread;
     mEvents = eventThread->createEventConnection();
-    mEventTube = mEvents->getDataChannel();
-    mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
+    mEvents->stealReceiveChannel(&mEventTube);
+    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT,
             MessageQueue::cb_eventReceiver, this);
 }
 
@@ -150,7 +149,7 @@
 int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
     ssize_t n;
     DisplayEventReceiver::Event buffer[8];
-    while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
+    while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
         for (int i=0 ; i<n ; i++) {
             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                 mHandler->dispatchInvalidate();
diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
index aed0aa9..85a33c8 100644
--- a/services/surfaceflinger/MessageQueue.h
+++ b/services/surfaceflinger/MessageQueue.h
@@ -25,6 +25,7 @@
 #include <utils/Timers.h>
 #include <utils/Looper.h>
 
+#include <private/gui/BitTube.h>
 #include <gui/DisplayEventReceiver.h>
 
 #include "Barrier.h"
@@ -81,7 +82,7 @@
     sp<Looper> mLooper;
     sp<EventThread> mEventThread;
     sp<IDisplayEventConnection> mEvents;
-    sp<BitTube> mEventTube;
+    gui::BitTube mEventTube;
     sp<Handler> mHandler;