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