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

Commit 5a1e9348 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Delete InputFlingerService_test

This test currently has 2 test cases:
1) sends an inputchannel via binder and then asks for it back. This is
   just implementation of the service, so it's just testing the
   implementation.
2) checks that an fd that's sent over binder remains non-blocking. A
   similar test was already committed into binderLibTest as
   aosp/2239719. This is general binder behaviour, and it's better if it
   lives next to the binder stuff. We don't need this test in input.
Therefore, delete this test. It's causing some crashes on hwasan devices
when libinput is linked statically, and the setup is too complicated to
get correctly (and the setup is already done for us in binderLibTest).

Bug: 217165277
Test: atest --host --no-bazel-mode inputflinger_tests libinput_tests
Change-Id: Iff9970465018e2a9ba73377c3332e014c870e160
parent b63e95b0
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -40,12 +40,10 @@ cc_test {
        "BlockingQueue_test.cpp",
        "EventHub_test.cpp",
        "FocusResolver_test.cpp",
        "IInputFlingerQuery.aidl",
        "InputProcessor_test.cpp",
        "InputProcessorConverter_test.cpp",
        "InputDispatcher_test.cpp",
        "InputReader_test.cpp",
        "InputFlingerService_test.cpp",
        "LatencyTracker_test.cpp",
        "PreferStylusOverTouch_test.cpp",
        "TestInputListener.cpp",
+0 −27
Original line number Diff line number Diff line
/**
 * Copyright (c) 2020, 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.
 */

import android.InputChannel;
import android.gui.FocusRequest;
import android.gui.WindowInfo;

/** @hide */
interface IInputFlingerQuery
{
    /* Test interfaces */
    void getInputChannels(out InputChannel[] channels);
    void resetInputManager();
}
+0 −243
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 <BnInputFlingerQuery.h>
#include <IInputFlingerQuery.h>

#include <android/os/BnInputFlinger.h>
#include <android/os/IInputFlinger.h>

#include <binder/Binder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>

#include <input/Input.h>
#include <input/InputTransport.h>

#include <gtest/gtest.h>
#include <inttypes.h>
#include <linux/uinput.h>
#include <log/log.h>
#include <chrono>
#include <thread>
#include <unordered_map>

#define TAG "InputFlingerServiceTest"

using android::gui::FocusRequest;
using android::os::BnInputFlinger;
using android::os::IInputFlinger;

using std::chrono_literals::operator""ms;
using std::chrono_literals::operator""s;

namespace android {

static const String16 kTestServiceName = String16("InputFlingerService");
static const String16 kQueryServiceName = String16("InputFlingerQueryService");

// --- InputFlingerServiceTest ---
class InputFlingerServiceTest : public testing::Test {
public:
    void SetUp() override;
    void TearDown() override;

protected:
    void InitializeInputFlinger();

    sp<IInputFlinger> mService;
    sp<IInputFlingerQuery> mQuery;

private:
    std::unique_ptr<InputChannel> mServerChannel, mClientChannel;
    std::mutex mLock;
};


class TestInputManager : public BnInputFlinger {
protected:
    virtual ~TestInputManager(){};

public:
    TestInputManager(){};

    binder::Status getInputChannels(std::vector<::android::InputChannel>* channels);

    status_t dump(int fd, const Vector<String16>& args) override;

    binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
    binder::Status removeInputChannel(const sp<IBinder>& connectionToken) override;
    binder::Status setFocusedWindow(const FocusRequest&) override;

    void reset();

private:
    mutable Mutex mLock;
    std::vector<std::shared_ptr<InputChannel>> mInputChannels;
};

class TestInputQuery : public BnInputFlingerQuery {
public:
    TestInputQuery(sp<android::TestInputManager> manager) : mManager(manager){};
    binder::Status getInputChannels(std::vector<::android::InputChannel>* channels) override;
    binder::Status resetInputManager() override;

private:
    sp<android::TestInputManager> mManager;
};

binder::Status TestInputQuery::getInputChannels(std::vector<::android::InputChannel>* channels) {
    return mManager->getInputChannels(channels);
}

binder::Status TestInputQuery::resetInputManager() {
    mManager->reset();
    return binder::Status::ok();
}

binder::Status TestInputManager::createInputChannel(const std::string& name,
                                                    InputChannel* outChannel) {
    AutoMutex _l(mLock);
    std::unique_ptr<InputChannel> serverChannel;
    std::unique_ptr<InputChannel> clientChannel;
    InputChannel::openInputChannelPair(name, serverChannel, clientChannel);

    clientChannel->copyTo(*outChannel);

    mInputChannels.emplace_back(std::move(serverChannel));

    return binder::Status::ok();
}

binder::Status TestInputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
    AutoMutex _l(mLock);

    auto it = std::find_if(mInputChannels.begin(), mInputChannels.end(),
                           [&](std::shared_ptr<InputChannel>& c) {
                               return c->getConnectionToken() == connectionToken;
                           });
    if (it != mInputChannels.end()) {
        mInputChannels.erase(it);
    }

    return binder::Status::ok();
}

status_t TestInputManager::dump(int fd, const Vector<String16>& args) {
    std::string dump;

    dump += " InputFlinger dump\n";

    ::write(fd, dump.c_str(), dump.size());
    return NO_ERROR;
}

binder::Status TestInputManager::getInputChannels(std::vector<::android::InputChannel>* channels) {
    channels->clear();
    for (std::shared_ptr<InputChannel>& channel : mInputChannels) {
        channels->push_back(*channel);
    }
    return binder::Status::ok();
}

binder::Status TestInputManager::setFocusedWindow(const FocusRequest& request) {
    return binder::Status::ok();
}

void TestInputManager::reset() {
    mInputChannels.clear();
}

void InputFlingerServiceTest::SetUp() {
    InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);
    InitializeInputFlinger();
}

void InputFlingerServiceTest::TearDown() {
    mQuery->resetInputManager();
}

void InputFlingerServiceTest::InitializeInputFlinger() {
    sp<IBinder> input(defaultServiceManager()->waitForService(kTestServiceName));
    ASSERT_TRUE(input != nullptr);
    mService = interface_cast<IInputFlinger>(input);

    input = defaultServiceManager()->waitForService(kQueryServiceName);
    ASSERT_TRUE(input != nullptr);
    mQuery = interface_cast<IInputFlingerQuery>(input);
}

/**
 *  Test InputFlinger service interface createInputChannel
 */
TEST_F(InputFlingerServiceTest, CreateInputChannelReturnsUnblockedFd) {
    // Test that the unblocked file descriptor flag is kept across processes over binder
    // transactions.

    InputChannel channel;
    ASSERT_TRUE(mService->createInputChannel("testchannels", &channel).isOk());

    const base::unique_fd& fd = channel.getFd();
    ASSERT_TRUE(fd.ok());

    const int result = fcntl(fd, F_GETFL);
    EXPECT_NE(result, -1);
    EXPECT_EQ(result & O_NONBLOCK, O_NONBLOCK);
}

TEST_F(InputFlingerServiceTest, CreateInputChannel) {
    InputChannel channel;
    ASSERT_TRUE(mService->createInputChannel("testchannels", &channel).isOk());

    std::vector<::android::InputChannel> channels;
    mQuery->getInputChannels(&channels);
    ASSERT_EQ(channels.size(), 1UL);
    EXPECT_EQ(channels[0].getConnectionToken(), channel.getConnectionToken());

    mService->removeInputChannel(channel.getConnectionToken());
    mQuery->getInputChannels(&channels);
    EXPECT_EQ(channels.size(), 0UL);
}

} // namespace android

int main(int argc, char** argv) {
    pid_t forkPid = fork();

    if (forkPid == 0) {
        // Server process
        android::sp<android::TestInputManager> manager =
                android::sp<android::TestInputManager>::make();
        android::sp<android::TestInputQuery> query =
                android::sp<android::TestInputQuery>::make(manager);

        android::defaultServiceManager()->addService(android::kTestServiceName, manager,
                                                     false /*allowIsolated*/);
        android::defaultServiceManager()->addService(android::kQueryServiceName, query,
                                                     false /*allowIsolated*/);
        android::ProcessState::self()->startThreadPool();
        android::IPCThreadState::self()->joinThreadPool();
    } else {
        android::ProcessState::self()->startThreadPool();
        ::testing::InitGoogleTest(&argc, argv);
        int result = RUN_ALL_TESTS();
        kill(forkPid, SIGKILL);
        return result;
    }
    return 0;
}