1 /*
2 * Copyright (C) 2016 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 "sensor_manager_hidl_hal_test"
18 #include <android-base/logging.h>
19
20 #include <sys/mman.h>
21
22 #include <chrono>
23 #include <thread>
24
25 #include <android/sensor.h>
26 #include <android/frameworks/sensorservice/1.0/ISensorManager.h>
27 #include <android/frameworks/sensorservice/1.0/types.h>
28 #include <android/hardware/sensors/1.0/types.h>
29 #include <android/hidl/allocator/1.0/IAllocator.h>
30 #include <gtest/gtest.h>
31 #include <sensors/convert.h>
32
33 using ::android::frameworks::sensorservice::V1_0::ISensorManager;
34 using ::android::frameworks::sensorservice::V1_0::Result;
35 using ::android::hardware::sensors::V1_0::Event;
36 using ::android::hardware::sensors::V1_0::RateLevel;
37 using ::android::hardware::sensors::V1_0::SensorFlagBits;
38 using ::android::hardware::sensors::V1_0::SensorFlagShift;
39 using ::android::hardware::sensors::V1_0::SensorType;
40 using ::android::hardware::sensors::V1_0::SensorsEventFormatOffset;
41 using ::android::hardware::Return;
42 using ::android::hardware::Void;
43 using ::android::hardware::hidl_memory;
44 using ::android::hidl::allocator::V1_0::IAllocator;
45 using ::android::sp;
46
47 template <typename T>
isOk(const Return<T> & ret)48 static inline ::testing::AssertionResult isOk(const Return<T> &ret) {
49 return (ret.isOk()
50 ? ::testing::AssertionSuccess()
51 : ::testing::AssertionFailure()) << ret.description();
52 }
53
54 template <>
55 __attribute__((__unused__))
isOk(const Return<Result> & ret)56 inline ::testing::AssertionResult isOk(const Return<Result> &ret) {
57 return ((ret.isOk() && ret == Result::OK)
58 ? ::testing::AssertionSuccess()
59 : ::testing::AssertionFailure())
60 << ret.description() << ", "
61 << (ret.isOk() ? toString(static_cast<Result>(ret)) : "");
62 }
63
isOk(Result result)64 static inline ::testing::AssertionResult isOk(Result result) {
65 using ::android::frameworks::sensorservice::V1_0::toString;
66 return (result == Result::OK
67 ? ::testing::AssertionSuccess()
68 : ::testing::AssertionFailure()) << toString(result);
69 }
70
71 template<typename I, typename F>
isIncreasing(I begin,I end,F getField)72 static ::testing::AssertionResult isIncreasing(I begin, I end, F getField) {
73 typename std::iterator_traits<I>::pointer lastValue = nullptr;
74 I iter;
75 size_t pos;
76 for (iter = begin, pos = 0; iter != end; ++iter, ++pos) {
77 if (iter == begin) {
78 lastValue = &(*iter);
79 continue;
80 }
81 if (getField(*iter) < getField(*lastValue)) {
82 return ::testing::AssertionFailure() << "Not an increasing sequence, pos = "
83 << pos << ", " << getField(*iter) << " < " << getField(*lastValue);
84 }
85 }
86 return ::testing::AssertionSuccess();
87 }
88
89 #define EXPECT_OK(__ret__) EXPECT_TRUE(isOk(__ret__))
90 #define ASSERT_OK(__ret__) ASSERT_TRUE(isOk(__ret__))
91
92 // The main test class for sensorservice HIDL HAL.
93 class SensorManagerTest : public ::testing::Test {
94 public:
SetUp()95 virtual void SetUp() override {
96 manager_ = ISensorManager::getService();
97 ASSERT_NE(manager_, nullptr);
98 ashmem_ = IAllocator::getService("ashmem");
99 ASSERT_NE(ashmem_, nullptr);
100 }
TearDown()101 virtual void TearDown() override {}
102
103 sp<ISensorManager> manager_;
104 sp<IAllocator> ashmem_;
105 };
106
107 // A class for test environment setup (kept since this file is a template).
108 class SensorManagerHidlEnvironment : public ::testing::Environment {
109 public:
SetUp()110 virtual void SetUp() {}
TearDown()111 virtual void TearDown() {}
112 };
113
114 using map_region = std::unique_ptr<void, std::function<void(void*)>>;
115
map(const hidl_memory & mem)116 map_region map(const hidl_memory &mem) {
117 if (mem.handle() == nullptr || mem.handle()->numFds != 1) {
118 return nullptr;
119 }
120 size_t size = mem.size();
121 void *buf = mmap(nullptr, size, PROT_READ, MAP_SHARED, mem.handle()->data[0], 0);
122 return map_region{buf, [size](void *localBuf) {
123 munmap(localBuf, size);
124 }};
125 }
126
127 /*
128 * Ping! make sure the service is alive.
129 */
TEST_F(SensorManagerTest,Ping)130 TEST_F(SensorManagerTest, Ping) {
131 EXPECT_OK(manager_->ping());
132 }
133
TEST_F(SensorManagerTest,List)134 TEST_F(SensorManagerTest, List) {
135 ASSERT_OK(manager_->getSensorList([] (__unused const auto &list, auto result) {
136 using ::android::hardware::sensors::V1_0::toString;
137 ASSERT_OK(result);
138 // Do something to the list of sensors.
139 }));
140 }
141
TEST_F(SensorManagerTest,Ashmem)142 TEST_F(SensorManagerTest, Ashmem) {
143
144 auto testOne = [this](uint64_t memSize, uint64_t intendedSize,
145 ISensorManager::createAshmemDirectChannel_cb callback) {
146 ASSERT_OK(ashmem_->allocate(memSize, [&](bool success, const auto &mem) {
147 ASSERT_TRUE(success);
148 ASSERT_NE(mem.handle(), nullptr);
149 ASSERT_OK(manager_->createAshmemDirectChannel(mem, intendedSize, callback));
150 }));
151 };
152
153 testOne(16, 16, [](const auto &chan, Result result) {
154 EXPECT_EQ(result, Result::BAD_VALUE) << "unexpected result when memory size is too small";
155 EXPECT_EQ(chan, nullptr);
156 });
157
158 testOne(1024, 1024, [](const auto &chan, Result result) {
159 EXPECT_OK(result);
160 EXPECT_NE(chan, nullptr);
161 });
162
163 testOne(1024, 2048, [](const auto &chan, Result result) {
164 EXPECT_EQ(result, Result::BAD_VALUE) << "unexpected result when intended size is too big";
165 EXPECT_EQ(chan, nullptr);
166 });
167
168 testOne(1024, 16, [](const auto &chan, Result result) {
169 EXPECT_EQ(result, Result::BAD_VALUE) << "unexpected result when intended size is too small";
170 EXPECT_EQ(chan, nullptr);
171 });
172 }
173
parseEvents(uint8_t * buf,size_t memSize)174 static std::vector<Event> parseEvents(uint8_t *buf, size_t memSize) {
175 using O = SensorsEventFormatOffset;
176 using ::android::hardware::sensors::V1_0::implementation::convertFromSensorEvent;
177 size_t offset = 0;
178 int64_t lastCounter = -1;
179 std::vector<Event> events;
180 Event event;
181
182 while(offset + (size_t)O::TOTAL_LENGTH <= memSize) {
183 uint8_t *start = buf + offset;
184 int64_t atomicCounter = *reinterpret_cast<uint32_t *>(start + (size_t)O::ATOMIC_COUNTER);
185 if (atomicCounter <= lastCounter) {
186 break;
187 }
188 int32_t size = *reinterpret_cast<int32_t *>(start + (size_t)O::SIZE_FIELD);
189 if (size != (size_t)O::TOTAL_LENGTH) {
190 // unknown error, events parsed may be wrong, remove all
191 events.clear();
192 break;
193 }
194
195 convertFromSensorEvent(*reinterpret_cast<const sensors_event_t *>(start), &event);
196 events.push_back(event);
197 lastCounter = atomicCounter;
198 offset += (size_t)O::TOTAL_LENGTH;
199 }
200 return events;
201 }
202
TEST_F(SensorManagerTest,Accelerometer)203 TEST_F(SensorManagerTest, Accelerometer) {
204 using std::literals::chrono_literals::operator""ms;
205 using ::android::hardware::sensors::V1_0::implementation::convertFromRateLevel;
206 Result getSensorResult;
207 int32_t handle;
208 ASSERT_OK(manager_->getDefaultSensor(SensorType::ACCELEROMETER, [&] (const auto &info, auto result) {
209 getSensorResult = result;
210 handle = info.sensorHandle;
211 if (result == Result::OK) {
212 ASSERT_TRUE(info.flags & SensorFlagBits::DIRECT_CHANNEL_ASHMEM);
213
214 int maxLevel = (info.flags & SensorFlagBits::MASK_DIRECT_REPORT)
215 >> (int)SensorFlagShift::DIRECT_REPORT;
216 ASSERT_TRUE(maxLevel >= convertFromRateLevel(RateLevel::FAST))
217 << "Accelerometer does not support fast report rate, test cannot proceed.";
218 }
219 }));
220 if (getSensorResult == Result::NOT_EXIST) {
221 LOG(WARNING) << "Cannot find accelerometer, skipped SensorManagerTest.Accelerometer";
222 return;
223 }
224 ASSERT_OK(getSensorResult);
225 const size_t memSize = (size_t)SensorsEventFormatOffset::TOTAL_LENGTH * 300;
226 ASSERT_OK(ashmem_->allocate(memSize, [&] (bool success, const auto &mem) {
227 ASSERT_TRUE(success);
228 map_region buf = map(mem);
229 ASSERT_NE(buf, nullptr);
230 ASSERT_OK(manager_->createAshmemDirectChannel(mem, memSize, [&](const auto &chan, Result result) {
231 ASSERT_OK(result);
232 ASSERT_NE(chan, nullptr);
233
234 int32_t returnedToken;
235 ASSERT_OK(chan->configure(handle, RateLevel::FAST, [&](auto token, auto res) {
236 ASSERT_OK(res);
237 ASSERT_GT(token, 0);
238 returnedToken = token;
239 })); // ~200Hz
240 std::this_thread::sleep_for(500ms);
241 ASSERT_OK(chan->configure(handle, RateLevel::STOP, [](auto token, auto res) {
242 ASSERT_OK(res);
243 ASSERT_EQ(token, 0);
244 }));
245
246 auto events = parseEvents(static_cast<uint8_t *>(buf.get()), memSize);
247
248 EXPECT_TRUE(isIncreasing(events.begin(), events.end(), [](const auto &event) {
249 return event.timestamp;
250 })) << "timestamp is not monotonically increasing";
251 for (const auto &event : events) {
252 EXPECT_EQ(returnedToken, event.sensorHandle)
253 << "configure token and sensor handle don't match.";
254 }
255 }));
256 }));
257 }
258
main(int argc,char ** argv)259 int main(int argc, char** argv) {
260 ::testing::AddGlobalTestEnvironment(new SensorManagerHidlEnvironment);
261 ::testing::InitGoogleTest(&argc, argv);
262 int status = RUN_ALL_TESTS();
263 LOG(INFO) << "Test result = " << status;
264 return status;
265 }
266