diff options
Diffstat (limited to 'services/inputflinger/tests/InputFlingerService_test.cpp')
-rw-r--r-- | services/inputflinger/tests/InputFlingerService_test.cpp | 462 |
1 files changed, 0 insertions, 462 deletions
diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp deleted file mode 100644 index c368e79f41..0000000000 --- a/services/inputflinger/tests/InputFlingerService_test.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/* - * 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/BnSetInputWindowsListener.h> -#include <android/os/IInputFlinger.h> -#include <android/os/ISetInputWindowsListener.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 <input/InputWindow.h> - -#include <gtest/gtest.h> -#include <inttypes.h> -#include <linux/uinput.h> -#include <log/log.h> -#include <ui/Rect.h> -#include <ui/Region.h> -#include <chrono> -#include <thread> -#include <unordered_map> - -#define TAG "InputFlingerServiceTest" - -using android::os::BnInputFlinger; -using android::os::BnSetInputWindowsListener; -using android::os::IInputFlinger; -using android::os::ISetInputWindowsListener; - -using std::chrono_literals::operator""ms; -using std::chrono_literals::operator""s; - -namespace android { - -static const sp<IBinder> TestInfoToken = new BBinder(); -static const sp<IBinder> FocusedTestInfoToken = new BBinder(); -static constexpr int32_t TestInfoId = 1; -static const std::string TestInfoName = "InputFlingerServiceTestInputWindowInfo"; -static constexpr Flags<InputWindowInfo::Flag> TestInfoFlags = InputWindowInfo::Flag::NOT_FOCUSABLE; -static constexpr InputWindowInfo::Type TestInfoType = InputWindowInfo::Type::INPUT_METHOD; -static constexpr std::chrono::duration TestInfoDispatchingTimeout = 2532ms; -static constexpr int32_t TestInfoFrameLeft = 93; -static constexpr int32_t TestInfoFrameTop = 34; -static constexpr int32_t TestInfoFrameRight = 16; -static constexpr int32_t TestInfoFrameBottom = 19; -static constexpr int32_t TestInfoSurfaceInset = 17; -static constexpr float TestInfoGlobalScaleFactor = 0.3; -static constexpr float TestInfoWindowXScale = 0.4; -static constexpr float TestInfoWindowYScale = 0.5; -static const Rect TestInfoTouchableRegionRect = {100 /* left */, 150 /* top */, 400 /* right */, - 450 /* bottom */}; -static const Region TestInfoTouchableRegion(TestInfoTouchableRegionRect); -static constexpr bool TestInfoVisible = false; -static constexpr bool TestInfoTrustedOverlay = true; -static constexpr bool TestInfoFocusable = false; -static constexpr bool TestInfoHasWallpaper = false; -static constexpr bool TestInfoPaused = false; -static constexpr int32_t TestInfoOwnerPid = 19; -static constexpr int32_t TestInfoOwnerUid = 24; -static constexpr InputWindowInfo::Feature TestInfoInputFeatures = - InputWindowInfo::Feature::NO_INPUT_CHANNEL; -static constexpr int32_t TestInfoDisplayId = 34; -static constexpr int32_t TestInfoPortalToDisplayId = 2; -static constexpr bool TestInfoReplaceTouchableRegionWithCrop = true; -static const sp<IBinder> TestInfoTouchableRegionCropHandle = new BBinder(); - -static const std::string TestAppInfoName = "InputFlingerServiceTestInputApplicationInfo"; -static const sp<IBinder> TestAppInfoToken = new BBinder(); -static constexpr std::chrono::duration TestAppInfoDispatchingTimeout = 12345678ms; - -static const String16 kTestServiceName = String16("InputFlingerService"); -static const String16 kQueryServiceName = String16("InputFlingerQueryService"); - -struct SetInputWindowsListener; -// --- InputFlingerServiceTest --- -class InputFlingerServiceTest : public testing::Test { -public: - void SetUp() override; - void TearDown() override; - -protected: - void InitializeInputFlinger(); - void setInputWindowsByInfos(const std::vector<InputWindowInfo>& infos); - void setFocusedWindow(const sp<IBinder> token, const sp<IBinder> focusedToken, - nsecs_t timestampNanos); - - void setInputWindowsFinished(); - void verifyInputWindowInfo(const InputWindowInfo& info) const; - InputWindowInfo& getInfo() const { return const_cast<InputWindowInfo&>(mInfo); } - - sp<IInputFlinger> mService; - sp<IInputFlingerQuery> mQuery; - -private: - sp<SetInputWindowsListener> mSetInputWindowsListener; - std::unique_ptr<InputChannel> mServerChannel, mClientChannel; - InputWindowInfo mInfo; - std::mutex mLock; - std::condition_variable mSetInputWindowsFinishedCondition; -}; - -struct SetInputWindowsListener : BnSetInputWindowsListener { - explicit SetInputWindowsListener(std::function<void()> cbFunc) : mCbFunc(cbFunc) {} - - binder::Status onSetInputWindowsFinished() override; - - std::function<void()> mCbFunc; -}; - -class TestInputManager : public BnInputFlinger { -protected: - virtual ~TestInputManager(){}; - -public: - TestInputManager(){}; - - binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles); - binder::Status getInputChannels(std::vector<::android::InputChannel>* channels); - binder::Status getLastFocusRequest(FocusRequest*); - - status_t dump(int fd, const Vector<String16>& args) override; - - binder::Status setInputWindows( - const std::vector<InputWindowInfo>& handles, - const sp<ISetInputWindowsListener>& setInputWindowsListener) 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::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mHandlesPerDisplay; - std::vector<std::shared_ptr<InputChannel>> mInputChannels; - FocusRequest mFocusRequest; -}; - -class TestInputQuery : public BnInputFlingerQuery { -public: - TestInputQuery(sp<android::TestInputManager> manager) : mManager(manager){}; - binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles) override; - binder::Status getInputChannels(std::vector<::android::InputChannel>* channels) override; - binder::Status getLastFocusRequest(FocusRequest*) override; - binder::Status resetInputManager() override; - -private: - sp<android::TestInputManager> mManager; -}; - -binder::Status TestInputQuery::getInputWindows( - std::vector<::android::InputWindowInfo>* inputHandles) { - return mManager->getInputWindows(inputHandles); -} - -binder::Status TestInputQuery::getInputChannels(std::vector<::android::InputChannel>* channels) { - return mManager->getInputChannels(channels); -} - -binder::Status TestInputQuery::getLastFocusRequest(FocusRequest* request) { - return mManager->getLastFocusRequest(request); -} - -binder::Status TestInputQuery::resetInputManager() { - mManager->reset(); - return binder::Status::ok(); -} - -binder::Status SetInputWindowsListener::onSetInputWindowsFinished() { - if (mCbFunc != nullptr) { - mCbFunc(); - } - return binder::Status::ok(); -} - -binder::Status TestInputManager::setInputWindows( - const std::vector<InputWindowInfo>& infos, - const sp<ISetInputWindowsListener>& setInputWindowsListener) { - AutoMutex _l(mLock); - - for (const auto& info : infos) { - mHandlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>()); - mHandlesPerDisplay[info.displayId].push_back(new InputWindowHandle(info)); - } - if (setInputWindowsListener) { - setInputWindowsListener->onSetInputWindowsFinished(); - } - 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::getInputWindows( - std::vector<::android::InputWindowInfo>* inputInfos) { - for (auto& [displayId, inputHandles] : mHandlesPerDisplay) { - for (auto& inputHandle : inputHandles) { - inputInfos->push_back(*inputHandle->getInfo()); - } - } - return binder::Status::ok(); -} - -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::getLastFocusRequest(FocusRequest* request) { - *request = mFocusRequest; - return binder::Status::ok(); -} - -binder::Status TestInputManager::setFocusedWindow(const FocusRequest& request) { - mFocusRequest = request; - return binder::Status::ok(); -} - -void TestInputManager::reset() { - mHandlesPerDisplay.clear(); - mInputChannels.clear(); - mFocusRequest = FocusRequest(); -} - -void InputFlingerServiceTest::SetUp() { - mSetInputWindowsListener = new SetInputWindowsListener([&]() { - std::unique_lock<std::mutex> lock(mLock); - mSetInputWindowsFinishedCondition.notify_all(); - }); - InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel); - - mInfo.token = TestInfoToken; - mInfo.id = TestInfoId; - mInfo.name = TestInfoName; - mInfo.flags = TestInfoFlags; - mInfo.type = TestInfoType; - mInfo.dispatchingTimeout = TestInfoDispatchingTimeout; - mInfo.frameLeft = TestInfoFrameLeft; - mInfo.frameTop = TestInfoFrameTop; - mInfo.frameRight = TestInfoFrameRight; - mInfo.frameBottom = TestInfoFrameBottom; - mInfo.surfaceInset = TestInfoSurfaceInset; - mInfo.globalScaleFactor = TestInfoGlobalScaleFactor; - mInfo.transform.set({TestInfoWindowXScale, 0, TestInfoFrameLeft, 0, TestInfoWindowYScale, - TestInfoFrameTop, 0, 0, 1}); - mInfo.touchableRegion = TestInfoTouchableRegion; - mInfo.visible = TestInfoVisible; - mInfo.trustedOverlay = TestInfoTrustedOverlay; - mInfo.focusable = TestInfoFocusable; - - mInfo.hasWallpaper = TestInfoHasWallpaper; - mInfo.paused = TestInfoPaused; - mInfo.ownerPid = TestInfoOwnerPid; - mInfo.ownerUid = TestInfoOwnerUid; - mInfo.inputFeatures = TestInfoInputFeatures; - mInfo.displayId = TestInfoDisplayId; - mInfo.portalToDisplayId = TestInfoPortalToDisplayId; - mInfo.replaceTouchableRegionWithCrop = TestInfoReplaceTouchableRegionWithCrop; - mInfo.touchableRegionCropHandle = TestInfoTouchableRegionCropHandle; - - mInfo.applicationInfo.name = TestAppInfoName; - mInfo.applicationInfo.token = TestAppInfoToken; - mInfo.applicationInfo.dispatchingTimeoutMillis = - std::chrono::duration_cast<std::chrono::milliseconds>(TestAppInfoDispatchingTimeout) - .count(); - - InitializeInputFlinger(); -} - -void InputFlingerServiceTest::TearDown() { - mQuery->resetInputManager(); -} - -void InputFlingerServiceTest::verifyInputWindowInfo(const InputWindowInfo& info) const { - EXPECT_EQ(mInfo, info); -} - -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); -} - -void InputFlingerServiceTest::setInputWindowsByInfos(const std::vector<InputWindowInfo>& infos) { - std::unique_lock<std::mutex> lock(mLock); - mService->setInputWindows(infos, mSetInputWindowsListener); - // Verify listener call - EXPECT_NE(mSetInputWindowsFinishedCondition.wait_for(lock, 1s), std::cv_status::timeout); -} - -void InputFlingerServiceTest::setFocusedWindow(const sp<IBinder> token, - const sp<IBinder> focusedToken, - nsecs_t timestampNanos) { - FocusRequest request; - request.token = TestInfoToken; - request.focusedToken = focusedToken; - request.timestamp = timestampNanos; - mService->setFocusedWindow(request); - // call set input windows and wait for the callback to drain the queue. - setInputWindowsByInfos(std::vector<InputWindowInfo>()); -} - -/** - * Test InputFlinger service interface SetInputWindows - */ -TEST_F(InputFlingerServiceTest, InputWindow_SetInputWindows) { - std::vector<InputWindowInfo> infos = {getInfo()}; - setInputWindowsByInfos(infos); - - // Verify input windows from service - std::vector<::android::InputWindowInfo> windowInfos; - mQuery->getInputWindows(&windowInfos); - for (const ::android::InputWindowInfo& windowInfo : windowInfos) { - verifyInputWindowInfo(windowInfo); - } -} - -/** - * 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, InputWindow_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); -} - -TEST_F(InputFlingerServiceTest, InputWindow_setFocusedWindow) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - setFocusedWindow(TestInfoToken, nullptr /* focusedToken */, now); - - FocusRequest request; - mQuery->getLastFocusRequest(&request); - - EXPECT_EQ(request.token, TestInfoToken); - EXPECT_EQ(request.focusedToken, nullptr); - EXPECT_EQ(request.timestamp, now); -} - -TEST_F(InputFlingerServiceTest, InputWindow_setFocusedWindowWithFocusedToken) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - setFocusedWindow(TestInfoToken, FocusedTestInfoToken, now); - - FocusRequest request; - mQuery->getLastFocusRequest(&request); - - EXPECT_EQ(request.token, TestInfoToken); - EXPECT_EQ(request.focusedToken, FocusedTestInfoToken); - EXPECT_EQ(request.timestamp, now); -} - -} // namespace android - -int main(int argc, char** argv) { - pid_t forkPid = fork(); - - if (forkPid == 0) { - // Server process - android::sp<android::TestInputManager> manager = new android::TestInputManager(); - android::sp<android::TestInputQuery> query = new android::TestInputQuery(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; -} |