1 /*
2 * Copyright (C) 2019 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 #include <android-base/logging.h>
18 #include <android-base/strings.h>
19 #include <android/hardware/automotive/can/1.0/ICanBus.h>
20 #include <android/hardware/automotive/can/1.0/types.h>
21 #include <can-vts-utils/can-hal-printers.h>
22 #include <gmock/gmock.h>
23 #include <hidl-utils/hidl-utils.h>
24 #include <hidl/GtestPrinter.h>
25 #include <hidl/ServiceManagement.h>
26
27 namespace android::hardware::automotive::can::V1_0::vts {
28
29 using hardware::hidl_vec;
30
31 struct CanMessageListener : public can::V1_0::ICanMessageListener {
onReceiveandroid::hardware::automotive::can::V1_0::vts::CanMessageListener32 virtual Return<void> onReceive(const can::V1_0::CanMessage&) override { return {}; }
33 };
34
35 struct CanErrorListener : public can::V1_0::ICanErrorListener {
onErrorandroid::hardware::automotive::can::V1_0::vts::CanErrorListener36 virtual Return<void> onError(ErrorEvent, bool) override { return {}; }
37 };
38
39 class CanBusHalTest : public ::testing::TestWithParam<std::string> {
40 protected:
41 virtual void SetUp() override;
42 virtual void TearDown() override;
43
44 std::tuple<Result, sp<ICloseHandle>> listen(const hidl_vec<CanMessageFilter>& filter,
45 const sp<ICanMessageListener>& listener);
46 sp<ICloseHandle> listenForErrors(const sp<ICanErrorListener>& listener);
47
48 sp<ICanBus> mCanBus;
49 };
50
SetUp()51 void CanBusHalTest::SetUp() {
52 mCanBus = ICanBus::getService(GetParam());
53 ASSERT_TRUE(mCanBus) << "Couldn't open CAN Bus: " << GetParam();
54 }
55
TearDown()56 void CanBusHalTest::TearDown() {
57 mCanBus.clear();
58 }
59
listen(const hidl_vec<CanMessageFilter> & filter,const sp<ICanMessageListener> & listener)60 std::tuple<Result, sp<ICloseHandle>> CanBusHalTest::listen(
61 const hidl_vec<CanMessageFilter>& filter, const sp<ICanMessageListener>& listener) {
62 Result halResult;
63 sp<ICloseHandle> closeHandle;
64 mCanBus->listen(filter, listener, hidl_utils::fill(&halResult, &closeHandle)).assertOk();
65
66 return {halResult, closeHandle};
67 }
68
listenForErrors(const sp<ICanErrorListener> & listener)69 sp<ICloseHandle> CanBusHalTest::listenForErrors(const sp<ICanErrorListener>& listener) {
70 const auto res = mCanBus->listenForErrors(listener);
71 res.assertOk();
72 return res;
73 }
74
TEST_P(CanBusHalTest,SendNoPayload)75 TEST_P(CanBusHalTest, SendNoPayload) {
76 CanMessage msg = {};
77 msg.id = 0x123;
78 ASSERT_NE(mCanBus, nullptr);
79 const auto result = mCanBus->send(msg);
80 ASSERT_EQ(Result::OK, result);
81 }
82
TEST_P(CanBusHalTest,Send8B)83 TEST_P(CanBusHalTest, Send8B) {
84 CanMessage msg = {};
85 msg.id = 0x234;
86 msg.payload = {1, 2, 3, 4, 5, 6, 7, 8};
87
88 const auto result = mCanBus->send(msg);
89 ASSERT_EQ(Result::OK, result);
90 }
91
TEST_P(CanBusHalTest,SendZeroId)92 TEST_P(CanBusHalTest, SendZeroId) {
93 CanMessage msg = {};
94 msg.payload = {1, 2, 3};
95
96 const auto result = mCanBus->send(msg);
97 ASSERT_EQ(Result::OK, result);
98 }
99
TEST_P(CanBusHalTest,SendTooLong)100 TEST_P(CanBusHalTest, SendTooLong) {
101 CanMessage msg = {};
102 msg.id = 0x123;
103 msg.payload = hidl_vec<uint8_t>(102400); // 100kiB
104
105 const auto result = mCanBus->send(msg);
106 ASSERT_EQ(Result::PAYLOAD_TOO_LONG, result);
107 }
108
TEST_P(CanBusHalTest,ListenNoFilter)109 TEST_P(CanBusHalTest, ListenNoFilter) {
110 const auto [result, closeHandle] = listen({}, new CanMessageListener());
111 ASSERT_EQ(Result::OK, result);
112
113 closeHandle->close().assertOk();
114 }
115
TEST_P(CanBusHalTest,ListenSomeFilter)116 TEST_P(CanBusHalTest, ListenSomeFilter) {
117 hidl_vec<CanMessageFilter> filters = {
118 {0x123, 0x1FF, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, false},
119 {0x001, 0x00F, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, true},
120 {0x200, 0x100, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, false},
121 };
122
123 const auto [result, closeHandle] = listen(filters, new CanMessageListener());
124 ASSERT_EQ(Result::OK, result);
125
126 closeHandle->close().assertOk();
127 }
128
TEST_P(CanBusHalTest,ListenNull)129 TEST_P(CanBusHalTest, ListenNull) {
130 const auto [result, closeHandle] = listen({}, nullptr);
131 ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
132 }
133
TEST_P(CanBusHalTest,DoubleCloseListener)134 TEST_P(CanBusHalTest, DoubleCloseListener) {
135 const auto [result, closeHandle] = listen({}, new CanMessageListener());
136 ASSERT_EQ(Result::OK, result);
137
138 closeHandle->close().assertOk();
139 closeHandle->close().assertOk();
140 }
141
TEST_P(CanBusHalTest,DontCloseListener)142 TEST_P(CanBusHalTest, DontCloseListener) {
143 const auto [result, closeHandle] = listen({}, new CanMessageListener());
144 ASSERT_EQ(Result::OK, result);
145 }
146
TEST_P(CanBusHalTest,DoubleCloseErrorListener)147 TEST_P(CanBusHalTest, DoubleCloseErrorListener) {
148 auto closeHandle = listenForErrors(new CanErrorListener());
149 ASSERT_NE(nullptr, closeHandle.get());
150
151 closeHandle->close().assertOk();
152 closeHandle->close().assertOk();
153 }
154
TEST_P(CanBusHalTest,DoubleCloseNullErrorListener)155 TEST_P(CanBusHalTest, DoubleCloseNullErrorListener) {
156 auto closeHandle = listenForErrors(nullptr);
157 ASSERT_NE(nullptr, closeHandle.get());
158
159 closeHandle->close().assertOk();
160 closeHandle->close().assertOk();
161 }
162
TEST_P(CanBusHalTest,DontCloseErrorListener)163 TEST_P(CanBusHalTest, DontCloseErrorListener) {
164 auto closeHandle = listenForErrors(new CanErrorListener());
165 ASSERT_NE(nullptr, closeHandle.get());
166 }
167
168 /**
169 * This test requires that you bring up a valid bus first.
170 *
171 * Before running:
172 * mma -j && adb root && adb remount && adb sync
173 *
174 * Example manual invocation:
175 * adb shell canhalctrl up <NAME_OF_VALID_BUS> socketcan can0 125000
176 * adb shell /data/nativetest64/VtsHalCanBusV1_0TargetTest/VtsHalCanBusV1_0TargetTest\
177 * --gtest_filter=*_<NAME_OF_VALID_BUS>
178 */
179 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CanBusHalTest);
180 INSTANTIATE_TEST_SUITE_P(PerInstance, CanBusHalTest,
181 testing::ValuesIn(getAllHalInstanceNames(ICanBus::descriptor)),
182 PrintInstanceNameToString);
183
184 } // namespace android::hardware::automotive::can::V1_0::vts
185