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

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

Merge "Second reland "Let InputFlinger create the server InputChannel""

parents 075b5985 1560166e
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -246,6 +246,8 @@ public:
    /* Return a new object that has a duplicate of this channel's fd. */
    /* Return a new object that has a duplicate of this channel's fd. */
    std::unique_ptr<InputChannel> dup() const;
    std::unique_ptr<InputChannel> dup() const;


    void copyTo(InputChannel& outChannel) const;

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


@@ -277,6 +279,8 @@ public:
    }
    }


private:
private:
    base::unique_fd dupFd() const;

    std::string mName;
    std::string mName;
    android::base::unique_fd mFd;
    android::base::unique_fd mFd;


+4 −7
Original line number Original line Diff line number Diff line
@@ -68,12 +68,10 @@ class InputSurface {
public:
public:
    InputSurface(const sp<SurfaceControl> &sc, int width, int height) {
    InputSurface(const sp<SurfaceControl> &sc, int width, int height) {
        mSurfaceControl = sc;
        mSurfaceControl = sc;
        std::unique_ptr<InputChannel> clientChannel;
        InputChannel::openInputChannelPair("testchannels", mServerChannel, clientChannel);
        mClientChannel = std::move(clientChannel);


        mInputFlinger = getInputFlinger();
        mInputFlinger = getInputFlinger();
        mInputFlinger->registerInputChannel(*mServerChannel);
        mClientChannel = std::make_shared<InputChannel>();
        mInputFlinger->createInputChannel("testchannels", mClientChannel.get());


        populateInputInfo(width, height);
        populateInputInfo(width, height);


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


    ~InputSurface() { mInputFlinger->unregisterInputChannel(mServerChannel->getConnectionToken()); }
    ~InputSurface() { mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken()); }


    void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
    void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
                    const sp<SurfaceControl>&)> transactionBody) {
                    const sp<SurfaceControl>&)> transactionBody) {
@@ -192,7 +190,7 @@ private:
    }
    }


    void populateInputInfo(int width, int height) {
    void populateInputInfo(int width, int height) {
        mInputInfo.token = mServerChannel->getConnectionToken();
        mInputInfo.token = mClientChannel->getConnectionToken();
        mInputInfo.name = "Test info";
        mInputInfo.name = "Test info";
        mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
        mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
        mInputInfo.type = InputWindowInfo::Type::BASE_APPLICATION;
        mInputInfo.type = InputWindowInfo::Type::BASE_APPLICATION;
@@ -219,7 +217,6 @@ private:
    }
    }
public:
public:
    sp<SurfaceControl> mSurfaceControl;
    sp<SurfaceControl> mSurfaceControl;
    std::unique_ptr<InputChannel> mServerChannel;
    std::shared_ptr<InputChannel> mClientChannel;
    std::shared_ptr<InputChannel> mClientChannel;
    sp<IInputFlinger> mInputFlinger;
    sp<IInputFlinger> mInputFlinger;


+24 −13
Original line number Original line Diff line number Diff line
@@ -377,22 +377,16 @@ status_t InputChannel::receiveMessage(InputMessage* msg) {
}
}


std::unique_ptr<InputChannel> InputChannel::dup() const {
std::unique_ptr<InputChannel> InputChannel::dup() const {
    android::base::unique_fd newFd(::dup(getFd()));
    base::unique_fd newFd(dupFd());
    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 nullptr;
    }
    return InputChannel::create(getName(), std::move(newFd), getConnectionToken());
    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 {
status_t InputChannel::writeToParcel(android::Parcel* parcel) const {
    if (parcel == nullptr) {
    if (parcel == nullptr) {
        ALOGE("%s: Null parcel", __func__);
        ALOGE("%s: Null parcel", __func__);
@@ -415,6 +409,23 @@ sp<IBinder> InputChannel::getConnectionToken() const {
    return mToken;
    return mToken;
}
}


base::unique_fd InputChannel::dupFd() const {
    android::base::unique_fd newFd(::dup(getFd()));
    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;
}

// --- InputPublisher ---
// --- InputPublisher ---


InputPublisher::InputPublisher(const std::shared_ptr<InputChannel>& channel) : mChannel(channel) {}
InputPublisher::InputPublisher(const std::shared_ptr<InputChannel>& channel) : mChannel(channel) {}
+2 −2
Original line number Original line Diff line number Diff line
@@ -30,8 +30,8 @@ interface IInputFlinger
    // shouldn't be a concern.
    // shouldn't be a concern.
    oneway void setInputWindows(in InputWindowInfo[] inputHandles,
    oneway void setInputWindows(in InputWindowInfo[] inputHandles,
            in @nullable ISetInputWindowsListener setInputWindowsListener);
            in @nullable ISetInputWindowsListener setInputWindowsListener);
    void registerInputChannel(in InputChannel channel);
    InputChannel createInputChannel(in @utf8InCpp String name);
    void unregisterInputChannel(in IBinder connectionToken);
    void removeInputChannel(in IBinder connectionToken);
    /**
    /**
     * Sets focus to the window identified by the token. This must be called
     * Sets focus to the window identified by the token. This must be called
     * after updating any input window handles.
     * after updating any input window handles.
+28 −4
Original line number Original line Diff line number Diff line
@@ -31,6 +31,25 @@


namespace android {
namespace android {


static int32_t exceptionCodeFromStatusT(status_t status) {
    switch (status) {
        case OK:
            return binder::Status::EX_NONE;
        case INVALID_OPERATION:
            return binder::Status::EX_UNSUPPORTED_OPERATION;
        case BAD_VALUE:
        case BAD_TYPE:
        case NAME_NOT_FOUND:
            return binder::Status::EX_ILLEGAL_ARGUMENT;
        case NO_INIT:
            return binder::Status::EX_ILLEGAL_STATE;
        case PERMISSION_DENIED:
            return binder::Status::EX_SECURITY;
        default:
            return binder::Status::EX_TRANSACTION_FAILED;
    }
}

InputManager::InputManager(
InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
@@ -119,7 +138,7 @@ binder::Status InputManager::setInputWindows(
}
}


// Used by tests only.
// Used by tests only.
binder::Status InputManager::registerInputChannel(const InputChannel& channel) {
binder::Status InputManager::createInputChannel(const std::string& name, InputChannel* outChannel) {
    IPCThreadState* ipc = IPCThreadState::self();
    IPCThreadState* ipc = IPCThreadState::self();
    const int uid = ipc->getCallingUid();
    const int uid = ipc->getCallingUid();
    if (uid != AID_SHELL && uid != AID_ROOT) {
    if (uid != AID_SHELL && uid != AID_ROOT) {
@@ -128,12 +147,17 @@ binder::Status InputManager::registerInputChannel(const InputChannel& channel) {
        return binder::Status::ok();
        return binder::Status::ok();
    }
    }


    mDispatcher->registerInputChannel(channel.dup());
    base::Result<std::unique_ptr<InputChannel>> channel = mDispatcher->createInputChannel(name);
    if (!channel) {
        return binder::Status::fromExceptionCode(exceptionCodeFromStatusT(channel.error().code()),
                                                 channel.error().message().c_str());
    }
    (*channel)->copyTo(*outChannel);
    return binder::Status::ok();
    return binder::Status::ok();
}
}


binder::Status InputManager::unregisterInputChannel(const sp<IBinder>& connectionToken) {
binder::Status InputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
    mDispatcher->unregisterInputChannel(connectionToken);
    mDispatcher->removeInputChannel(connectionToken);
    return binder::Status::ok();
    return binder::Status::ok();
}
}


Loading