Use aidl-defined InputChannel for parceling

Currently, InputChannel is a manually-written parcelable. In this CL, we
introduce an aidl-defined InputChannel, which eventually could also be
used in Java as well.

Now, whenever an InputChannel needs to be written to parcel, we first
create the new android.os.InputChannel and then write that object to
parcel.

Eventually, we can convert the Java side of InputChannel to use this
mechanism, as well.

Bug: 161009324
Test: adb shell monkey 1000
Test: atest libgui_test
Change-Id: Ib44c5ff02b3c77e0425b59a76195ed100e187317
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 2d64872..8b1c2a3 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -35,18 +35,16 @@
 #include <android-base/result.h>
 #include <android-base/unique_fd.h>
 
+#include <android/os/InputChannelCore.h>
 #include <binder/IBinder.h>
-#include <binder/Parcelable.h>
 #include <input/Input.h>
 #include <input/InputVerifier.h>
 #include <sys/stat.h>
 #include <ui/Transform.h>
 #include <utils/BitSet.h>
 #include <utils/Errors.h>
-#include <utils/RefBase.h>
 #include <utils/Timers.h>
 
-
 namespace android {
 class Parcel;
 
@@ -231,18 +229,15 @@
  * input messages across processes.  Each channel has a descriptive name for debugging purposes.
  *
  * Each endpoint has its own InputChannel object that specifies its file descriptor.
+ * For parceling, this relies on android::os::InputChannelCore, defined in aidl.
  *
  * The input channel is closed when all references to it are released.
  */
-class InputChannel : public Parcelable {
+class InputChannel : private android::os::InputChannelCore {
 public:
-    static std::unique_ptr<InputChannel> create(const std::string& name,
-                                                android::base::unique_fd fd, sp<IBinder> token);
-    InputChannel() = default;
-    InputChannel(const InputChannel& other)
-          : mName(other.mName), mFd(other.dupFd()), mToken(other.mToken){};
-    InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token);
-    ~InputChannel() override;
+    static std::unique_ptr<InputChannel> create(android::os::InputChannelCore&& parceledChannel);
+    ~InputChannel();
+
     /**
      * Create a pair of input channels.
      * The two returned input channels are equivalent, and are labeled as "server" and "client"
@@ -254,9 +249,8 @@
                                          std::unique_ptr<InputChannel>& outServerChannel,
                                          std::unique_ptr<InputChannel>& outClientChannel);
 
-    inline std::string getName() const { return mName; }
-    inline const android::base::unique_fd& getFd() const { return mFd; }
-    inline sp<IBinder> getToken() const { return mToken; }
+    inline std::string getName() const { return name; }
+    inline int getFd() const { return fd.get(); }
 
     /* Send a message to the other endpoint.
      *
@@ -304,10 +298,7 @@
     /* Return a new object that has a duplicate of this channel's fd. */
     std::unique_ptr<InputChannel> dup() const;
 
-    void copyTo(InputChannel& outChannel) const;
-
-    status_t readFromParcel(const android::Parcel* parcel) override;
-    status_t writeToParcel(android::Parcel* parcel) const override;
+    void copyTo(android::os::InputChannelCore& outChannel) const;
 
     /**
      * The connection token is used to identify the input connection, i.e.
@@ -323,26 +314,11 @@
      */
     sp<IBinder> getConnectionToken() const;
 
-    bool operator==(const InputChannel& inputChannel) const {
-        struct stat lhs, rhs;
-        if (fstat(mFd.get(), &lhs) != 0) {
-            return false;
-        }
-        if (fstat(inputChannel.getFd().get(), &rhs) != 0) {
-            return false;
-        }
-        // If file descriptors are pointing to same inode they are duplicated fds.
-        return inputChannel.getName() == getName() && inputChannel.getConnectionToken() == mToken &&
-                lhs.st_ino == rhs.st_ino;
-    }
-
 private:
-    base::unique_fd dupFd() const;
+    static std::unique_ptr<InputChannel> create(const std::string& name,
+                                                android::base::unique_fd fd, sp<IBinder> token);
 
-    std::string mName;
-    base::unique_fd mFd;
-
-    sp<IBinder> mToken;
+    InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token);
 };
 
 /*
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index b9ab803..a9d6e8d 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -63,8 +63,7 @@
 using Transaction = SurfaceComposerClient::Transaction;
 
 sp<IInputFlinger> getInputFlinger() {
-   sp<IBinder> input(defaultServiceManager()->getService(
-            String16("inputflinger")));
+    sp<IBinder> input(defaultServiceManager()->waitForService(String16("inputflinger")));
     if (input == nullptr) {
         ALOGE("Failed to link to input service");
     } else { ALOGE("Linked to input"); }
@@ -104,8 +103,13 @@
         if (noInputChannel) {
             mInputInfo.setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true);
         } else {
-            mClientChannel = std::make_shared<InputChannel>();
-            mInputFlinger->createInputChannel("testchannels", mClientChannel.get());
+            android::os::InputChannelCore tempChannel;
+            android::binder::Status result =
+                    mInputFlinger->createInputChannel("testchannels", &tempChannel);
+            if (!result.isOk()) {
+                ADD_FAILURE() << "binder call to createInputChannel failed";
+            }
+            mClientChannel = InputChannel::create(std::move(tempChannel));
             mInputInfo.token = mClientChannel->getConnectionToken();
             mInputConsumer = new InputConsumer(mClientChannel);
         }
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 3d3bf13..e5fb2c5 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -175,6 +175,7 @@
     ],
     srcs: [
         "android/os/IInputFlinger.aidl",
+        "android/os/InputChannelCore.aidl",
         "AccelerationCurve.cpp",
         "Input.cpp",
         "InputDevice.cpp",
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 37de00c..0e0e80d 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -95,6 +95,21 @@
     return __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Resampling", ANDROID_LOG_INFO);
 }
 
+android::base::unique_fd dupChannelFd(int fd) {
+    android::base::unique_fd newFd(::dup(fd));
+    if (!newFd.ok()) {
+        ALOGE("Could not duplicate fd %i : %s", fd, strerror(errno));
+        const bool hitFdLimit = errno == EMFILE || errno == ENFILE;
+        // If this process is out of file descriptors, then throwing that might end up exploding
+        // on the other side of a binder call, which isn't really helpful.
+        // Better to just crash here and hope that the FD leak is slow.
+        // Other failures could be client errors, so we still propagate those back to the caller.
+        LOG_ALWAYS_FATAL_IF(hitFdLimit, "Too many open files, could not duplicate input channel");
+        return {};
+    }
+    return newFd;
+}
+
 } // namespace
 
 using android::base::Result;
@@ -395,15 +410,23 @@
     return std::unique_ptr<InputChannel>(new InputChannel(name, std::move(fd), token));
 }
 
-InputChannel::InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token)
-      : mName(std::move(name)), mFd(std::move(fd)), mToken(std::move(token)) {
+std::unique_ptr<InputChannel> InputChannel::create(
+        android::os::InputChannelCore&& parceledChannel) {
+    return InputChannel::create(parceledChannel.name, parceledChannel.fd.release(),
+                                parceledChannel.token);
+}
+
+InputChannel::InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token) {
+    this->name = std::move(name);
+    this->fd.reset(std::move(fd));
+    this->token = std::move(token);
     ALOGD_IF(DEBUG_CHANNEL_LIFECYCLE, "Input channel constructed: name='%s', fd=%d",
-             getName().c_str(), getFd().get());
+             getName().c_str(), getFd());
 }
 
 InputChannel::~InputChannel() {
     ALOGD_IF(DEBUG_CHANNEL_LIFECYCLE, "Input channel destroyed: name='%s', fd=%d",
-             getName().c_str(), getFd().get());
+             getName().c_str(), getFd());
 }
 
 status_t InputChannel::openInputChannelPair(const std::string& name,
@@ -441,19 +464,19 @@
     ATRACE_NAME_IF(ATRACE_ENABLED(),
                    StringPrintf("sendMessage(inputChannel=%s, seq=0x%" PRIx32 ", type=0x%" PRIx32
                                 ")",
-                                mName.c_str(), msg->header.seq, msg->header.type));
+                                name.c_str(), msg->header.seq, msg->header.type));
     const size_t msgLength = msg->size();
     InputMessage cleanMsg;
     msg->getSanitizedCopy(&cleanMsg);
     ssize_t nWrite;
     do {
-        nWrite = ::send(getFd().get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
+        nWrite = ::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
     } while (nWrite == -1 && errno == EINTR);
 
     if (nWrite < 0) {
         int error = errno;
         ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ error sending message of type %s, %s",
-                 mName.c_str(), ftl::enum_string(msg->header.type).c_str(), strerror(error));
+                 name.c_str(), ftl::enum_string(msg->header.type).c_str(), strerror(error));
         if (error == EAGAIN || error == EWOULDBLOCK) {
             return WOULD_BLOCK;
         }
@@ -465,12 +488,12 @@
 
     if (size_t(nWrite) != msgLength) {
         ALOGD_IF(DEBUG_CHANNEL_MESSAGES,
-                 "channel '%s' ~ error sending message type %s, send was incomplete", mName.c_str(),
+                 "channel '%s' ~ error sending message type %s, send was incomplete", name.c_str(),
                  ftl::enum_string(msg->header.type).c_str());
         return DEAD_OBJECT;
     }
 
-    ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ sent message of type %s", mName.c_str(),
+    ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ sent message of type %s", name.c_str(),
              ftl::enum_string(msg->header.type).c_str());
 
     return OK;
@@ -479,13 +502,13 @@
 status_t InputChannel::receiveMessage(InputMessage* msg) {
     ssize_t nRead;
     do {
-        nRead = ::recv(getFd().get(), msg, sizeof(InputMessage), MSG_DONTWAIT);
+        nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT);
     } while (nRead == -1 && errno == EINTR);
 
     if (nRead < 0) {
         int error = errno;
         ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ receive message failed, errno=%d",
-                 mName.c_str(), errno);
+                 name.c_str(), errno);
         if (error == EAGAIN || error == EWOULDBLOCK) {
             return WOULD_BLOCK;
         }
@@ -497,29 +520,29 @@
 
     if (nRead == 0) { // check for EOF
         ALOGD_IF(DEBUG_CHANNEL_MESSAGES,
-                 "channel '%s' ~ receive message failed because peer was closed", mName.c_str());
+                 "channel '%s' ~ receive message failed because peer was closed", name.c_str());
         return DEAD_OBJECT;
     }
 
     if (!msg->isValid(nRead)) {
-        ALOGE("channel '%s' ~ received invalid message of size %zd", mName.c_str(), nRead);
+        ALOGE("channel '%s' ~ received invalid message of size %zd", name.c_str(), nRead);
         return BAD_VALUE;
     }
 
-    ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ received message of type %s", mName.c_str(),
+    ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ received message of type %s", name.c_str(),
              ftl::enum_string(msg->header.type).c_str());
     if (ATRACE_ENABLED()) {
         // Add an additional trace point to include data about the received message.
         std::string message = StringPrintf("receiveMessage(inputChannel=%s, seq=0x%" PRIx32
                                            ", type=0x%" PRIx32 ")",
-                                           mName.c_str(), msg->header.seq, msg->header.type);
+                                           name.c_str(), msg->header.seq, msg->header.type);
         ATRACE_NAME(message.c_str());
     }
     return OK;
 }
 
 bool InputChannel::probablyHasInput() const {
-    struct pollfd pfds = {.fd = mFd, .events = POLLIN};
+    struct pollfd pfds = {.fd = fd.get(), .events = POLLIN};
     if (::poll(&pfds, /*nfds=*/1, /*timeout=*/0) <= 0) {
         // This can be a false negative because EINTR and ENOMEM are not handled. The latter should
         // be extremely rare. The EINTR is also unlikely because it happens only when the signal
@@ -538,7 +561,7 @@
     if (timeout < 0ms) {
         LOG(FATAL) << "Timeout cannot be negative, received " << timeout.count();
     }
-    struct pollfd pfds = {.fd = mFd, .events = POLLIN};
+    struct pollfd pfds = {.fd = fd.get(), .events = POLLIN};
     int ret;
     std::chrono::time_point<std::chrono::steady_clock> stopTime =
             std::chrono::steady_clock::now() + timeout;
@@ -551,53 +574,18 @@
 }
 
 std::unique_ptr<InputChannel> InputChannel::dup() const {
-    base::unique_fd newFd(dupFd());
+    base::unique_fd newFd(dupChannelFd(fd.get()));
     return InputChannel::create(getName(), std::move(newFd), getConnectionToken());
 }
 
-void InputChannel::copyTo(InputChannel& outChannel) const {
-    outChannel.mName = getName();
-    outChannel.mFd = dupFd();
-    outChannel.mToken = getConnectionToken();
-}
-
-status_t InputChannel::writeToParcel(android::Parcel* parcel) const {
-    if (parcel == nullptr) {
-        ALOGE("%s: Null parcel", __func__);
-        return BAD_VALUE;
-    }
-    return parcel->writeStrongBinder(mToken)
-            ?: parcel->writeUtf8AsUtf16(mName) ?: parcel->writeUniqueFileDescriptor(mFd);
-}
-
-status_t InputChannel::readFromParcel(const android::Parcel* parcel) {
-    if (parcel == nullptr) {
-        ALOGE("%s: Null parcel", __func__);
-        return BAD_VALUE;
-    }
-    mToken = parcel->readStrongBinder();
-    return parcel->readUtf8FromUtf16(&mName) ?: parcel->readUniqueFileDescriptor(&mFd);
+void InputChannel::copyTo(android::os::InputChannelCore& outChannel) const {
+    outChannel.name = getName();
+    outChannel.fd.reset(dupChannelFd(fd.get()));
+    outChannel.token = getConnectionToken();
 }
 
 sp<IBinder> InputChannel::getConnectionToken() const {
-    return mToken;
-}
-
-base::unique_fd InputChannel::dupFd() const {
-    base::unique_fd newFd(::dup(getFd().get()));
-    if (!newFd.ok()) {
-        ALOGE("Could not duplicate fd %i for channel %s: %s", getFd().get(), getName().c_str(),
-              strerror(errno));
-        const bool hitFdLimit = errno == EMFILE || errno == ENFILE;
-        // If this process is out of file descriptors, then throwing that might end up exploding
-        // on the other side of a binder call, which isn't really helpful.
-        // Better to just crash here and hope that the FD leak is slow.
-        // Other failures could be client errors, so we still propagate those back to the caller.
-        LOG_ALWAYS_FATAL_IF(hitFdLimit, "Too many open files, could not duplicate input channel %s",
-                            getName().c_str());
-        return {};
-    }
-    return newFd;
+    return token;
 }
 
 // --- InputPublisher ---
diff --git a/libs/input/android/os/IInputFlinger.aidl b/libs/input/android/os/IInputFlinger.aidl
index 00ebd4d..c1aacfb 100644
--- a/libs/input/android/os/IInputFlinger.aidl
+++ b/libs/input/android/os/IInputFlinger.aidl
@@ -16,14 +16,13 @@
 
 package android.os;
 
-import android.InputChannel;
+import android.os.InputChannelCore;
 import android.gui.FocusRequest;
-import android.gui.WindowInfo;
 
 /** @hide */
 interface IInputFlinger
 {
-    InputChannel createInputChannel(in @utf8InCpp String name);
+    InputChannelCore createInputChannel(in @utf8InCpp String name);
     void removeInputChannel(in IBinder connectionToken);
     /**
      * Sets focus to the window identified by the token. This must be called
diff --git a/libs/input/android/InputChannel.aidl b/libs/input/android/os/InputChannelCore.aidl
similarity index 72%
rename from libs/input/android/InputChannel.aidl
rename to libs/input/android/os/InputChannelCore.aidl
index c2d1112..888a553 100644
--- a/libs/input/android/InputChannel.aidl
+++ b/libs/input/android/os/InputChannelCore.aidl
@@ -15,6 +15,16 @@
 ** limitations under the License.
 */
 
-package android;
+package android.os;
 
-parcelable InputChannel cpp_header "input/InputTransport.h";
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Input channel struct for sending InputChannel between processes.
+ * @hide
+ */
+parcelable InputChannelCore {
+    @utf8InCpp String name;
+    ParcelFileDescriptor fd;
+    IBinder token;
+}
diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp
index 650c930..60feb53 100644
--- a/libs/input/tests/InputChannel_test.cpp
+++ b/libs/input/tests/InputChannel_test.cpp
@@ -32,37 +32,31 @@
 
 namespace android {
 
+namespace {
+bool operator==(const InputChannel& left, const InputChannel& right) {
+    struct stat lhs, rhs;
+    if (fstat(left.getFd(), &lhs) != 0) {
+        return false;
+    }
+    if (fstat(right.getFd(), &rhs) != 0) {
+        return false;
+    }
+    // If file descriptors are pointing to same inode they are duplicated fds.
+    return left.getName() == right.getName() &&
+            left.getConnectionToken() == right.getConnectionToken() && lhs.st_ino == rhs.st_ino;
+}
+} // namespace
+
 class InputChannelTest : public testing::Test {
 };
 
+TEST_F(InputChannelTest, ClientAndServerTokensMatch) {
+    std::unique_ptr<InputChannel> serverChannel, clientChannel;
 
-TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
-    // Our purpose here is to verify that the input channel destructor closes the
-    // file descriptor provided to it.  One easy way is to provide it with one end
-    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
-    Pipe pipe;
-
-    android::base::unique_fd sendFd(pipe.sendFd);
-
-    std::unique_ptr<InputChannel> inputChannel =
-            InputChannel::create("channel name", std::move(sendFd), new BBinder());
-
-    EXPECT_NE(inputChannel, nullptr) << "channel should be successfully created";
-    EXPECT_STREQ("channel name", inputChannel->getName().c_str())
-            << "channel should have provided name";
-    EXPECT_NE(-1, inputChannel->getFd()) << "channel should have valid fd";
-
-    // InputChannel should be the owner of the file descriptor now
-    ASSERT_FALSE(sendFd.ok());
-}
-
-TEST_F(InputChannelTest, SetAndGetToken) {
-    Pipe pipe;
-    sp<IBinder> token = new BBinder();
-    std::unique_ptr<InputChannel> channel =
-            InputChannel::create("test channel", android::base::unique_fd(pipe.sendFd), token);
-
-    EXPECT_EQ(token, channel->getConnectionToken());
+    status_t result =
+            InputChannel::openInputChannelPair("channel name", serverChannel, clientChannel);
+    ASSERT_EQ(OK, result) << "should have successfully opened a channel pair";
+    EXPECT_EQ(serverChannel->getConnectionToken(), clientChannel->getConnectionToken());
 }
 
 TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
@@ -71,8 +65,7 @@
     status_t result = InputChannel::openInputChannelPair("channel name",
             serverChannel, clientChannel);
 
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
+    ASSERT_EQ(OK, result) << "should have successfully opened a channel pair";
 
     // Name
     EXPECT_STREQ("channel name (server)", serverChannel->getName().c_str())
@@ -235,25 +228,6 @@
     }
 }
 
-TEST_F(InputChannelTest, InputChannelParcelAndUnparcel) {
-    std::unique_ptr<InputChannel> serverChannel, clientChannel;
-
-    status_t result =
-            InputChannel::openInputChannelPair("channel parceling", serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result) << "should have successfully opened a channel pair";
-
-    InputChannel chan;
-    Parcel parcel;
-    ASSERT_EQ(OK, serverChannel->writeToParcel(&parcel));
-    parcel.setDataPosition(0);
-    chan.readFromParcel(&parcel);
-
-    EXPECT_EQ(chan == *serverChannel, true)
-            << "inputchannel should be equal after parceling and unparceling.\n"
-            << "name " << chan.getName() << " name " << serverChannel->getName();
-}
-
 TEST_F(InputChannelTest, DuplicateChannelAndAssertEqual) {
     std::unique_ptr<InputChannel> serverChannel, clientChannel;
 
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 4863513..823df67 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -260,13 +260,16 @@
 }
 
 // Used by tests only.
-binder::Status InputManager::createInputChannel(const std::string& name, InputChannel* outChannel) {
+binder::Status InputManager::createInputChannel(const std::string& name,
+                                                android::os::InputChannelCore* outChannel) {
     IPCThreadState* ipc = IPCThreadState::self();
-    const int uid = ipc->getCallingUid();
+    const uid_t uid = ipc->getCallingUid();
     if (uid != AID_SHELL && uid != AID_ROOT) {
-        ALOGE("Invalid attempt to register input channel over IPC"
-                "from non shell/root entity (PID: %d)", ipc->getCallingPid());
-        return binder::Status::ok();
+        LOG(ERROR) << __func__ << " can only be called by SHELL or ROOT users, "
+                   << "but was called from UID " << uid;
+        return binder::Status::
+                fromExceptionCode(EX_SECURITY,
+                                  "This uid is not allowed to call createInputChannel");
     }
 
     base::Result<std::unique_ptr<InputChannel>> channel = mDispatcher->createInputChannel(name);
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index df944ef..c479aaf 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -136,7 +136,8 @@
     void dump(std::string& dump) override;
 
     status_t dump(int fd, const Vector<String16>& args) override;
-    binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
+    binder::Status createInputChannel(const std::string& name,
+                                      android::os::InputChannelCore* outChannel) override;
     binder::Status removeInputChannel(const sp<IBinder>& connectionToken) override;
     binder::Status setFocusedWindow(const gui::FocusRequest&) override;
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index c349a58..47560c8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -5827,7 +5827,7 @@
         for (const auto& [token, connection] : mConnectionsByToken) {
             dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
                                          "status=%s, monitor=%s, responsive=%s\n",
-                                 connection->inputChannel->getFd().get(),
+                                 connection->inputChannel->getFd(),
                                  connection->getInputChannelName().c_str(),
                                  connection->getWindowName().c_str(),
                                  ftl::enum_string(connection->status).c_str(),
@@ -5914,7 +5914,7 @@
     { // acquire lock
         std::scoped_lock _l(mLock);
         const sp<IBinder>& token = serverChannel->getConnectionToken();
-        auto&& fd = serverChannel->getFd();
+        const int fd = serverChannel->getFd();
         std::shared_ptr<Connection> connection =
                 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
                                              mIdGenerator);
@@ -5927,7 +5927,7 @@
         std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
                                                             this, std::placeholders::_1, token);
 
-        mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
+        mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
                        nullptr);
     } // release lock
 
@@ -5957,7 +5957,7 @@
         std::shared_ptr<Connection> connection =
                 std::make_shared<Connection>(serverChannel, /*monitor=*/true, mIdGenerator);
         const sp<IBinder>& token = serverChannel->getConnectionToken();
-        auto&& fd = serverChannel->getFd();
+        const int fd = serverChannel->getFd();
 
         if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
             ALOGE("Created a new connection, but the token %p is already known", token.get());
@@ -5968,7 +5968,7 @@
 
         mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
 
-        mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
+        mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
                        nullptr);
     }
 
@@ -6007,7 +6007,7 @@
         removeMonitorChannelLocked(connectionToken);
     }
 
-    mLooper->removeFd(connection->inputChannel->getFd().get());
+    mLooper->removeFd(connection->inputChannel->getFd());
 
     nsecs_t currentTime = now();
     abortBrokenDispatchCycleLocked(currentTime, connection, notify);
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index f1f4a61..271e462 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -1113,7 +1113,7 @@
 
     sp<IBinder> getToken() { return mConsumer.getChannel()->getConnectionToken(); }
 
-    int getChannelFd() { return mConsumer.getChannel()->getFd().get(); }
+    int getChannelFd() { return mConsumer.getChannel()->getFd(); }
 
 private:
     InputConsumer mConsumer;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index aa6be36..776eccb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5733,7 +5733,7 @@
         case ISurfaceComposerClient::eFXSurfaceContainer:
         case ISurfaceComposerClient::eFXSurfaceBufferState:
             args.flags |= ISurfaceComposerClient::eNoColorFill;
-            FMT_FALLTHROUGH;
+            [[fallthrough]];
         case ISurfaceComposerClient::eFXSurfaceEffect: {
             result = createBufferStateLayer(args, &outResult.handle, &layer);
             std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();