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