Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61847ccb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use std::shared_ptr for InputChannel"

parents 40143e40 ce5ab080
Loading
Loading
Loading
Loading
+30 −42
Original line number Diff line number Diff line
@@ -183,18 +183,6 @@ struct InputMessage {
    }
};

struct InputChannelInfo : public Parcelable {
    std::string mName;
    android::base::unique_fd mFd;
    sp<IBinder> mToken;

    InputChannelInfo() = default;
    InputChannelInfo(const std::string& name, android::base::unique_fd fd, sp<IBinder> token)
          : mName(name), mFd(std::move(fd)), mToken(token){};
    status_t readFromParcel(const android::Parcel* parcel) override;
    status_t writeToParcel(android::Parcel* parcel) const override;
};

/*
 * An input channel consists of a local unix domain socket used to send and receive
 * input messages across processes.  Each channel has a descriptive name for debugging purposes.
@@ -203,14 +191,15 @@ struct InputChannelInfo : public Parcelable {
 *
 * The input channel is closed when all references to it are released.
 */
class InputChannel : public RefBase {
class InputChannel : public Parcelable {
public:
    InputChannel();
    static std::shared_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(::dup(other.mFd)), mToken(other.mToken){};
    InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token);
    virtual ~InputChannel();

    static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd,
                                   sp<IBinder> token);

    /**
     * Create a pair of input channels.
     * The two returned input channels are equivalent, and are labeled as "server" and "client"
@@ -219,12 +208,12 @@ public:
     * Return OK on success.
     */
    static status_t openInputChannelPair(const std::string& name,
            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
                                         std::shared_ptr<InputChannel>& outServerChannel,
                                         std::shared_ptr<InputChannel>& outClientChannel);

    inline std::string getName() const { return mInfo.mName; }
    inline int getFd() const { return mInfo.mFd.get(); }
    inline sp<IBinder> getToken() const { return mInfo.mToken; }
    inline InputChannelInfo& getInfo() { return mInfo; }
    inline std::string getName() const { return mName; }
    inline const android::base::unique_fd& getFd() const { return mFd; }
    inline sp<IBinder> getToken() const { return mToken; }

    /* Send a message to the other endpoint.
     *
@@ -252,11 +241,10 @@ public:
    status_t receiveMessage(InputMessage* msg);

    /* Return a new object that has a duplicate of this channel's fd. */
    sp<InputChannel> dup() const;

    status_t readFromParcel(const android::Parcel* parcel);
    std::shared_ptr<InputChannel> dup() const;

    status_t writeToParcel(android::Parcel* parcel) const;
    status_t readFromParcel(const android::Parcel* parcel) override;
    status_t writeToParcel(android::Parcel* parcel) const override;

    /**
     * The connection token is used to identify the input connection, i.e.
@@ -273,22 +261,23 @@ public:
    sp<IBinder> getConnectionToken() const;

    bool operator==(const InputChannel& inputChannel) const {
        struct stat lhsInfo, rhsInfo;
        if (fstat(mInfo.mFd.get(), &lhsInfo) != 0) {
        struct stat lhs, rhs;
        if (fstat(mFd.get(), &lhs) != 0) {
            return false;
        }
        if (fstat(inputChannel.getFd(), &rhsInfo) != 0) {
        if (fstat(inputChannel.getFd(), &rhs) != 0) {
            return false;
        }
        // If file descriptors are pointing to same inode they are duplicated fds.
        return inputChannel.getName() == getName() &&
                inputChannel.getConnectionToken() == mInfo.mToken &&
                lhsInfo.st_ino == rhsInfo.st_ino;
        return inputChannel.getName() == getName() && inputChannel.getConnectionToken() == mToken &&
                lhs.st_ino == rhs.st_ino;
    }

private:
    InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token);
    InputChannelInfo mInfo;
    std::string mName;
    android::base::unique_fd mFd;

    sp<IBinder> mToken;
};

/*
@@ -297,13 +286,13 @@ private:
class InputPublisher {
public:
    /* Creates a publisher associated with an input channel. */
    explicit InputPublisher(const sp<InputChannel>& channel);
    explicit InputPublisher(const std::shared_ptr<InputChannel>& channel);

    /* Destroys the publisher and releases its input channel. */
    ~InputPublisher();

    /* Gets the underlying input channel. */
    inline sp<InputChannel> getChannel() { return mChannel; }
    inline std::shared_ptr<InputChannel> getChannel() { return mChannel; }

    /* Publishes a key event to the input channel.
     *
@@ -360,7 +349,7 @@ public:
    status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);

private:
    sp<InputChannel> mChannel;
    std::shared_ptr<InputChannel> mChannel;
};

/*
@@ -369,13 +358,13 @@ private:
class InputConsumer {
public:
    /* Creates a consumer associated with an input channel. */
    explicit InputConsumer(const sp<InputChannel>& channel);
    explicit InputConsumer(const std::shared_ptr<InputChannel>& channel);

    /* Destroys the consumer and releases its input channel. */
    ~InputConsumer();

    /* Gets the underlying input channel. */
    inline sp<InputChannel> getChannel() { return mChannel; }
    inline std::shared_ptr<InputChannel> getChannel() { return mChannel; }

    /* Consumes an input event from the input channel and copies its contents into
     * an InputEvent object created using the specified factory.
@@ -451,8 +440,7 @@ private:
    // True if touch resampling is enabled.
    const bool mResampleTouch;

    // The input channel.
    sp<InputChannel> mChannel;
    std::shared_ptr<InputChannel> mChannel;

    // The current input message.
    InputMessage mMsg;
+4 −3
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public:
        InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);

        mInputFlinger = getInputFlinger();
        mInputFlinger->registerInputChannel(mServerChannel->getInfo());
        mInputFlinger->registerInputChannel(*mServerChannel);

        populateInputInfo(width, height);

@@ -154,7 +154,7 @@ public:
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
    }

    ~InputSurface() { mInputFlinger->unregisterInputChannel(mServerChannel->getInfo()); }
    ~InputSurface() { mInputFlinger->unregisterInputChannel(*mServerChannel); }

    void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
                    const sp<SurfaceControl>&)> transactionBody) {
@@ -211,7 +211,8 @@ private:
    }
public:
    sp<SurfaceControl> mSurfaceControl;
    sp<InputChannel> mServerChannel, mClientChannel;
    std::shared_ptr<InputChannel> mServerChannel;
    std::shared_ptr<InputChannel> mClientChannel;
    sp<IInputFlinger> mInputFlinger;

    InputWindowInfo mInputInfo;
+31 −48
Original line number Diff line number Diff line
@@ -241,65 +241,42 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const {
    }
}

// --- InputChannelInfo ---

status_t InputChannelInfo::writeToParcel(android::Parcel* parcel) const {
    if (parcel == nullptr) {
        ALOGE("%s: Null parcel", __func__);
        return BAD_VALUE;
    }
    status_t status = parcel->writeStrongBinder(mToken)
            ?: parcel->writeUtf8AsUtf16(mName) ?: parcel->writeUniqueFileDescriptor(mFd);
    return status;
}

status_t InputChannelInfo::readFromParcel(const android::Parcel* parcel) {
    if (parcel == nullptr) {
        ALOGE("%s: Null parcel", __func__);
        return BAD_VALUE;
    }
    mToken = parcel->readStrongBinder();
    status_t status = parcel->readUtf8FromUtf16(&mName) ?: parcel->readUniqueFileDescriptor(&mFd);
    return status;
}

// --- InputChannel ---

sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd,
                                      sp<IBinder> token) {
std::shared_ptr<InputChannel> InputChannel::create(const std::string& name,
                                                   android::base::unique_fd fd, sp<IBinder> token) {
    const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
    if (result != 0) {
        LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
                         strerror(errno));
        return nullptr;
    }
    return new InputChannel(name, std::move(fd), token);
    // using 'new' to access a non-public constructor
    return std::shared_ptr<InputChannel>(new InputChannel(name, std::move(fd), token));
}

InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token)
      : mInfo(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)) {
    if (DEBUG_CHANNEL_LIFECYCLE) {
        ALOGD("Input channel constructed: name='%s', fd=%d", mInfo.mName.c_str(), mInfo.mFd.get());
        ALOGD("Input channel constructed: name='%s', fd=%d", getName().c_str(), getFd().get());
    }
}

InputChannel::InputChannel() {}

InputChannel::~InputChannel() {
    if (DEBUG_CHANNEL_LIFECYCLE) {
        ALOGD("Input channel destroyed: name='%s', fd=%d", getName().c_str(), getFd());
        ALOGD("Input channel destroyed: name='%s', fd=%d", getName().c_str(), getFd().get());
    }
}

status_t InputChannel::openInputChannelPair(const std::string& name,
        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
                                            std::shared_ptr<InputChannel>& outServerChannel,
                                            std::shared_ptr<InputChannel>& outClientChannel) {
    int sockets[2];
    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
        status_t result = -errno;
        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d",
                name.c_str(), errno);
        outServerChannel.clear();
        outClientChannel.clear();
        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d", name.c_str(), errno);
        outServerChannel.reset();
        outClientChannel.reset();
        return result;
    }

@@ -399,10 +376,10 @@ status_t InputChannel::receiveMessage(InputMessage* msg) {
    return OK;
}

sp<InputChannel> InputChannel::dup() const {
std::shared_ptr<InputChannel> InputChannel::dup() const {
    android::base::unique_fd newFd(::dup(getFd()));
    if (!newFd.ok()) {
        ALOGE("Could not duplicate fd %i for channel %s: %s", getFd(), getName().c_str(),
        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
@@ -417,22 +394,30 @@ sp<InputChannel> InputChannel::dup() const {
}

status_t InputChannel::writeToParcel(android::Parcel* parcel) const {
    return mInfo.writeToParcel(parcel);
    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) {
    return mInfo.readFromParcel(parcel);
    if (parcel == nullptr) {
        ALOGE("%s: Null parcel", __func__);
        return BAD_VALUE;
    }
    mToken = parcel->readStrongBinder();
    return parcel->readUtf8FromUtf16(&mName) ?: parcel->readUniqueFileDescriptor(&mFd);
}

sp<IBinder> InputChannel::getConnectionToken() const {
    return mInfo.mToken;
    return mToken;
}

// --- InputPublisher ---

InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
        mChannel(channel) {
}
InputPublisher::InputPublisher(const std::shared_ptr<InputChannel>& channel) : mChannel(channel) {}

InputPublisher::~InputPublisher() {
}
@@ -596,10 +581,8 @@ status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandle

// --- InputConsumer ---

InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
        mResampleTouch(isTouchResamplingEnabled()),
        mChannel(channel), mMsgDeferred(false) {
}
InputConsumer::InputConsumer(const std::shared_ptr<InputChannel>& channel)
      : mResampleTouch(isTouchResamplingEnabled()), mChannel(channel), mMsgDeferred(false) {}

InputConsumer::~InputConsumer() {
}
+1 −1
Original line number Diff line number Diff line
@@ -17,4 +17,4 @@

package android;

parcelable InputChannelInfo cpp_header "input/InputTransport.h";
parcelable InputChannel cpp_header "input/InputTransport.h";
+3 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package android.os;

import android.InputChannelInfo;
import android.InputChannel;
import android.InputWindowInfo;
import android.os.ISetInputWindowsListener;

@@ -29,6 +29,6 @@ interface IInputFlinger
    // shouldn't be a concern.
    oneway void setInputWindows(in InputWindowInfo[] inputHandles,
            in @nullable ISetInputWindowsListener setInputWindowsListener);
    void registerInputChannel(in InputChannelInfo info);
    void unregisterInputChannel(in InputChannelInfo info);
    void registerInputChannel(in InputChannel channel);
    void unregisterInputChannel(in InputChannel channel);
}
Loading