xref: /aosp_15_r20/frameworks/native/libs/input/tests/TestInputChannel.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /**
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "TestInputChannel"
18 #define ATRACE_TAG ATRACE_TAG_INPUT
19 
20 #include <TestInputChannel.h>
21 
22 #include <sys/socket.h>
23 #include <unistd.h>
24 
25 #include <array>
26 
27 #include <android-base/logging.h>
28 #include <android-base/unique_fd.h>
29 #include <binder/IBinder.h>
30 #include <utils/StrongPointer.h>
31 
32 namespace android {
33 
34 namespace {
35 
36 /**
37  * Returns a stub file descriptor by opening a socket pair and closing one of the fds. The returned
38  * fd can be used to construct an InputChannel.
39  */
generateFileDescriptor()40 base::unique_fd generateFileDescriptor() {
41     std::array<int, 2> kFileDescriptors;
42     LOG_IF(FATAL, ::socketpair(AF_UNIX, SOCK_SEQPACKET, 0, kFileDescriptors.data()) != 0)
43             << "TestInputChannel. Failed to create socket pair.";
44     LOG_IF(FATAL, ::close(kFileDescriptors[1]) != 0)
45             << "TestInputChannel. Failed to close file descriptor.";
46     return base::unique_fd{kFileDescriptors[0]};
47 }
48 } // namespace
49 
50 // --- TestInputChannel ---
51 
TestInputChannel(const std::string & name)52 TestInputChannel::TestInputChannel(const std::string& name)
53       : InputChannel{name, generateFileDescriptor(), sp<BBinder>::make()} {}
54 
enqueueMessage(const InputMessage & message)55 void TestInputChannel::enqueueMessage(const InputMessage& message) {
56     mReceivedMessages.push(message);
57 }
58 
sendMessage(const InputMessage * message)59 status_t TestInputChannel::sendMessage(const InputMessage* message) {
60     LOG_IF(FATAL, message == nullptr)
61             << "TestInputChannel " << getName() << ". No message was passed to sendMessage.";
62 
63     mSentMessages.push(*message);
64     return OK;
65 }
66 
receiveMessage()67 base::Result<InputMessage> TestInputChannel::receiveMessage() {
68     if (mReceivedMessages.empty()) {
69         return base::Error(WOULD_BLOCK);
70     }
71     InputMessage message = mReceivedMessages.front();
72     mReceivedMessages.pop();
73     return message;
74 }
75 
probablyHasInput() const76 bool TestInputChannel::probablyHasInput() const {
77     return !mReceivedMessages.empty();
78 }
79 
assertFinishMessage(uint32_t seq,bool handled)80 void TestInputChannel::assertFinishMessage(uint32_t seq, bool handled) {
81     ASSERT_FALSE(mSentMessages.empty())
82             << "TestInputChannel " << getName() << ". Cannot assert. mSentMessages is empty.";
83 
84     const InputMessage& finishMessage = mSentMessages.front();
85 
86     EXPECT_EQ(finishMessage.header.seq, seq)
87             << "TestInputChannel " << getName()
88             << ". Sequence mismatch. Message seq: " << finishMessage.header.seq
89             << " Expected seq: " << seq;
90 
91     EXPECT_EQ(finishMessage.body.finished.handled, handled)
92             << "TestInputChannel " << getName()
93             << ". Handled value mismatch. Message val: " << std::boolalpha
94             << finishMessage.body.finished.handled << "Expected val: " << handled
95             << std::noboolalpha;
96     mSentMessages.pop();
97 }
98 
assertNoSentMessages() const99 void TestInputChannel::assertNoSentMessages() const {
100     ASSERT_TRUE(mSentMessages.empty());
101 }
102 } // namespace android