blob: 4f0d9522c9ed7fb524ceaa0ecf74941bb3e0195b [file] [log] [blame]
Iliyan Malchevb31e10c2016-08-13 23:03:25 -07001#define LOG_TAG "hidl_test"
Andreas Huber9cd48d02016-08-03 14:25:59 -07002#include <android-base/logging.h>
3
Steven Moreland88ca4512016-08-11 11:24:10 -07004#include <android/hardware/tests/foo/1.0/BnFoo.h>
5#include <android/hardware/tests/foo/1.0/BnFooCallback.h>
6#include <android/hardware/tests/bar/1.0/BnBar.h>
Andreas Huber9cd48d02016-08-03 14:25:59 -07007
Yifan Hong1dc87932016-08-19 09:51:01 -07008#include <gtest/gtest.h>
Iliyan Malchev0acf4192016-08-22 19:33:20 -07009#include <inttypes.h>
Yifan Hong1dc87932016-08-19 09:51:01 -070010#if GTEST_IS_THREADSAFE
11#include <sys/types.h>
12#include <signal.h>
13#include <errno.h>
14#include <pthread.h>
15#else
16#error "GTest did not detect pthread library."
17#endif
18
Martijn Coenen7473fab2016-08-19 14:05:40 +020019#include <hidl/IServiceManager.h>
Martijn Coenen93915102016-09-01 01:35:52 +020020#include <hidl/Status.h>
Andreas Huber9cd48d02016-08-03 14:25:59 -070021#include <hwbinder/IPCThreadState.h>
Andreas Huber9cd48d02016-08-03 14:25:59 -070022#include <hwbinder/ProcessState.h>
Andreas Huber9cd48d02016-08-03 14:25:59 -070023
Iliyan Malchev0acf4192016-08-22 19:33:20 -070024#include <utils/Condition.h>
25#include <utils/Timers.h>
26
Steven Moreland88ca4512016-08-11 11:24:10 -070027using ::android::hardware::tests::foo::V1_0::BnFoo;
28using ::android::hardware::tests::foo::V1_0::BnFooCallback;
29using ::android::hardware::tests::bar::V1_0::BnBar;
30using ::android::hardware::tests::foo::V1_0::IFoo;
31using ::android::hardware::tests::foo::V1_0::IFooCallback;
32using ::android::hardware::tests::bar::V1_0::IBar;
Steven Moreland40786312016-08-16 10:29:40 -070033using ::android::hardware::tests::bar::V1_0::IHwBar;
Steven Moreland88ca4512016-08-11 11:24:10 -070034using ::android::hardware::tests::foo::V1_0::Abc;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -070035using ::android::hardware::Return;
Andreas Huber8a82ff72016-08-04 10:29:39 -070036using ::android::hardware::Status;
37using ::android::hardware::hidl_vec;
38using ::android::hardware::hidl_string;
Andreas Huber9cd48d02016-08-03 14:25:59 -070039using ::android::sp;
Iliyan Malchev0acf4192016-08-22 19:33:20 -070040using ::android::Mutex;
41using ::android::Condition;
Andreas Huber9cd48d02016-08-03 14:25:59 -070042
Steven Moreland40786312016-08-16 10:29:40 -070043struct FooCallback : public IFooCallback {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070044 FooCallback() : invokeInfo{}, mLock{}, mCond{} {}
Iliyan Malchevd856b052016-08-16 22:25:27 -070045 Status heyItsYou(const sp<IFooCallback> &cb) override;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -070046 Return<bool> heyItsYouIsntIt(const sp<IFooCallback> &cb) override;
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070047 Status heyItsTheMeaningOfLife(uint8_t tmol) override;
Iliyan Malchev0acf4192016-08-22 19:33:20 -070048 Status reportResults(int64_t ns, reportResults_cb cb) override;
49 Status youBlockedMeFor(const int64_t ns[3]) override;
50
Steven Moreland60bce222016-09-07 10:17:43 -070051 static constexpr nsecs_t DELAY_S = 1;
Iliyan Malchev0acf4192016-08-22 19:33:20 -070052 static constexpr nsecs_t DELAY_NS = seconds_to_nanoseconds(DELAY_S);
53 static constexpr nsecs_t TOLERANCE_NS = milliseconds_to_nanoseconds(10);
54 static constexpr nsecs_t ONEWAY_TOLERANCE_NS = milliseconds_to_nanoseconds(1);
55
56 InvokeInfo invokeInfo[3];
57 Mutex mLock;
58 Condition mCond;
Andreas Huber9cd48d02016-08-03 14:25:59 -070059};
60
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070061Status FooCallback::heyItsYou(
62 const sp<IFooCallback> &_cb) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070063 nsecs_t start = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070064 ALOGI("SERVER(FooCallback) heyItsYou cb = %p", _cb.get());
Iliyan Malchev0acf4192016-08-22 19:33:20 -070065 mLock.lock();
66 invokeInfo[0].invoked = true;
67 invokeInfo[0].timeNs = systemTime() - start;
68 mCond.signal();
69 mLock.unlock();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070070 return Status::ok();
71}
Andreas Huber9cd48d02016-08-03 14:25:59 -070072
Iliyan Malchev2b6591b2016-08-18 19:15:19 -070073Return<bool> FooCallback::heyItsYouIsntIt(const sp<IFooCallback> &_cb) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070074 nsecs_t start = systemTime();
75 ALOGI("SERVER(FooCallback) heyItsYouIsntIt cb = %p sleeping for %" PRId64 " seconds", _cb.get(), DELAY_S);
76 sleep(DELAY_S);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070077 ALOGI("SERVER(FooCallback) heyItsYouIsntIt cb = %p responding", _cb.get());
Iliyan Malchev0acf4192016-08-22 19:33:20 -070078 mLock.lock();
79 invokeInfo[1].invoked = true;
80 invokeInfo[1].timeNs = systemTime() - start;
81 mCond.signal();
82 mLock.unlock();
Iliyan Malchevd856b052016-08-16 22:25:27 -070083 return true;
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070084}
85
86Status FooCallback::heyItsTheMeaningOfLife(uint8_t tmol) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070087 nsecs_t start = systemTime();
88 ALOGI("SERVER(FooCallback) heyItsTheMeaningOfLife = %d sleeping for %" PRId64 " seconds", tmol, DELAY_S);
89 sleep(DELAY_S);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070090 ALOGI("SERVER(FooCallback) heyItsTheMeaningOfLife = %d done sleeping", tmol);
Iliyan Malchev0acf4192016-08-22 19:33:20 -070091 mLock.lock();
92 invokeInfo[2].invoked = true;
93 invokeInfo[2].timeNs = systemTime() - start;
94 mCond.signal();
95 mLock.unlock();
96 return Status::ok();
97}
98
99Status FooCallback::reportResults(int64_t ns, reportResults_cb cb) {
Andreas Huber03866f52016-08-30 14:19:52 -0700100 ALOGI("SERVER(FooCallback) reportResults(%" PRId64 " seconds)", nanoseconds_to_seconds(ns));
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700101 nsecs_t leftToWaitNs = ns;
102 mLock.lock();
103 while (!(invokeInfo[0].invoked && invokeInfo[1].invoked && invokeInfo[2].invoked) &&
104 leftToWaitNs > 0) {
105 nsecs_t start = systemTime();
106 ::android::status_t rc = mCond.waitRelative(mLock, leftToWaitNs);
107 if (rc != ::android::OK) {
Andreas Huber03866f52016-08-30 14:19:52 -0700108 ALOGI("SERVER(FooCallback)::reportResults(%" PRId64 " ns) Condition::waitRelative(%" PRId64 ") returned error (%d)", ns, leftToWaitNs, rc);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700109 break;
110 }
Andreas Huber03866f52016-08-30 14:19:52 -0700111 ALOGI("SERVER(FooCallback)::reportResults(%" PRId64 " ns) Condition::waitRelative was signalled", ns);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700112 leftToWaitNs -= systemTime() - start;
113 }
114 mLock.unlock();
115 cb(leftToWaitNs, invokeInfo);
116 return Status::ok();
117}
118
119Status FooCallback::youBlockedMeFor(const int64_t ns[3]) {
120 for (size_t i = 0; i < 3; i++) {
121 invokeInfo[i].callerBlockedNs = ns[i];
122 }
Andreas Huber9cd48d02016-08-03 14:25:59 -0700123 return Status::ok();
124}
125
Steven Moreland40786312016-08-16 10:29:40 -0700126struct Bar : public IBar {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700127 Status doThis(float param) override;
128
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700129 Return<int32_t> doThatAndReturnSomething(int64_t param) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700130
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700131 Return<double> doQuiteABit(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700132 int32_t a,
133 int64_t b,
134 float c,
Iliyan Malchevd856b052016-08-16 22:25:27 -0700135 double d) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700136
137 Status doSomethingElse(
138 const int32_t param[15], doSomethingElse_cb _cb) override;
139
140 Status doStuffAndReturnAString(
141 doStuffAndReturnAString_cb _cb) override;
142
143 Status mapThisVector(
144 const hidl_vec<int32_t> &param, mapThisVector_cb _cb) override;
145
146 Status callMe(
147 const sp<IFooCallback> &cb) override;
148
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700149 Return<SomeEnum> useAnEnum(SomeEnum param) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700150
Steven Moreland88ca4512016-08-11 11:24:10 -0700151 Status haveAGooberVec(const hidl_vec<Goober>& param) override;
152 Status haveAGoober(const Goober &g) override;
153 Status haveAGooberArray(const Goober lots[20]) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700154
Steven Moreland88ca4512016-08-11 11:24:10 -0700155 Status haveATypeFromAnotherFile(const Abc &def) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700156
157 Status haveSomeStrings(
158 const hidl_string array[3],
159 haveSomeStrings_cb _cb) override;
160
161 Status haveAStringVec(
162 const hidl_vec<hidl_string> &vector,
163 haveAStringVec_cb _cb) override;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700164
165 Status thisIsNew() override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700166};
167
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700168Status Bar::doThis(float param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700169 ALOGI("SERVER(Bar) doThis(%.2f)", param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700170
171 return Status::ok();
172}
173
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700174Return<int32_t> Bar::doThatAndReturnSomething(
Iliyan Malchevd856b052016-08-16 22:25:27 -0700175 int64_t param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700176 ALOGI("SERVER(Bar) doThatAndReturnSomething(%ld)", param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700177
Iliyan Malchevd856b052016-08-16 22:25:27 -0700178 return 666;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700179}
180
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700181Return<double> Bar::doQuiteABit(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700182 int32_t a,
183 int64_t b,
184 float c,
Iliyan Malchevd856b052016-08-16 22:25:27 -0700185 double d) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700186 ALOGI("SERVER(Bar) doQuiteABit(%d, %ld, %.2f, %.2f)", a, b, c, d);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700187
Iliyan Malchevd856b052016-08-16 22:25:27 -0700188 return 666.5;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700189}
190
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700191Status Bar::doSomethingElse(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700192 const int32_t param[15], doSomethingElse_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700193 ALOGI("SERVER(Bar) doSomethingElse(...)");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700194
195 int32_t result[32] = { 0 };
196 for (size_t i = 0; i < 15; ++i) {
197 result[i] = 2 * param[i];
198 result[15 + i] = param[i];
199 }
200 result[30] = 1;
201 result[31] = 2;
202
203 _cb(result);
204
205 return Status::ok();
206}
207
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700208Status Bar::doStuffAndReturnAString(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700209 doStuffAndReturnAString_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700210 ALOGI("SERVER(Bar) doStuffAndReturnAString");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700211
212 hidl_string s;
213 s = "Hello, world";
214
215 _cb(s);
216
217 return Status::ok();
218}
219
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700220Status Bar::mapThisVector(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700221 const hidl_vec<int32_t> &param, mapThisVector_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700222 ALOGI("SERVER(Bar) mapThisVector");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700223
224 hidl_vec<int32_t> out;
Andreas Huber899b0632016-08-15 12:21:19 -0700225 out.resize(param.size());
Steven Moreland88ca4512016-08-11 11:24:10 -0700226
227 for (size_t i = 0; i < out.size(); ++i) {
228 out[i] = param[i] * 2;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700229 }
230
231 _cb(out);
232
Andreas Huber9cd48d02016-08-03 14:25:59 -0700233 return Status::ok();
234}
235
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700236Status Bar::callMe(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700237 const sp<IFooCallback> &cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700238 ALOGI("SERVER(Bar) callMe %p", cb.get());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700239
240 if (cb != NULL) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700241
242 nsecs_t c[3];
243 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYou, " \
244 "should return immediately", cb.get());
245 c[0] = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700246 cb->heyItsYou(cb);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700247 c[0] = systemTime() - c[0];
248 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYou " \
249 "returned after %" PRId64 "ns", cb.get(), c[0]);
250
251 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYouIsntIt, " \
252 "should block for %" PRId64 " seconds", cb.get(),
253 FooCallback::DELAY_S);
254 c[1] = systemTime();
Iliyan Malchevd856b052016-08-16 22:25:27 -0700255 bool answer = cb->heyItsYouIsntIt(cb);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700256 c[1] = systemTime() - c[1];
257 ALOGI("SERVER(Bar) callMe %p IFooCallback::heyItsYouIsntIt " \
258 "responded with %d after %" PRId64 "ns", cb.get(), answer, c[1]);
259
260 ALOGI("SERVER(Bar) callMe %p calling " \
261 "IFooCallback::heyItsTheMeaningOfLife, " \
262 "should return immediately ", cb.get());
263 c[2] = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700264 cb->heyItsTheMeaningOfLife(42);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700265 c[2] = systemTime() - c[2];
266 ALOGI("SERVER(Bar) callMe %p After call to " \
267 "IFooCallback::heyItsTheMeaningOfLife " \
268 "responded after %" PRId64 "ns", cb.get(), c[2]);
269
270 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::youBlockedMeFor " \
271 "to report times", cb.get());
272 cb->youBlockedMeFor(c);
273 ALOGI("SERVER(Bar) callMe %p After call to " \
274 "IFooCallback::heyYouBlockedMeFor", cb.get());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700275 }
276
277 return Status::ok();
278}
279
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700280Return<Bar::SomeEnum> Bar::useAnEnum(SomeEnum param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700281 ALOGI("SERVER(Bar) useAnEnum %d", (int)param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700282
Iliyan Malchevd856b052016-08-16 22:25:27 -0700283 return SomeEnum::goober;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700284}
285
Steven Moreland88ca4512016-08-11 11:24:10 -0700286Status Bar::haveAGooberVec(const hidl_vec<Goober>& param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700287 ALOGI("SERVER(Bar) haveAGooberVec &param = %p", &param);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700288
289 return Status::ok();
290}
291
Steven Moreland88ca4512016-08-11 11:24:10 -0700292Status Bar::haveAGoober(const Goober &g) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700293 ALOGI("SERVER(Bar) haveaGoober g=%p", &g);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700294
295 return Status::ok();
296}
297
Steven Moreland88ca4512016-08-11 11:24:10 -0700298Status Bar::haveAGooberArray(const Goober lots[20]) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700299 ALOGI("SERVER(Bar) haveAGooberArray lots = %p", lots);
Steven Moreland88ca4512016-08-11 11:24:10 -0700300
301 return Status::ok();
302}
303
304Status Bar::haveATypeFromAnotherFile(const Abc &def) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700305 ALOGI("SERVER(Bar) haveATypeFromAnotherFile def=%p", &def);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700306
307 return Status::ok();
308}
309
310Status Bar::haveSomeStrings(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700311 const hidl_string array[3],
312 haveSomeStrings_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700313 ALOGI("SERVER(Bar) haveSomeStrings([\"%s\", \"%s\", \"%s\"])",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700314 array[0].c_str(),
315 array[1].c_str(),
316 array[2].c_str());
317
318 hidl_string result[2];
319 result[0] = "Hello";
320 result[1] = "World";
321
322 _cb(result);
323
324 return Status::ok();
325}
326
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700327Status Bar::haveAStringVec(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700328 const hidl_vec<hidl_string> &vector,
329 haveAStringVec_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700330 ALOGI("SERVER(Bar) haveAStringVec([\"%s\", \"%s\", \"%s\"])",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700331 vector[0].c_str(),
332 vector[1].c_str(),
333 vector[2].c_str());
334
335 hidl_vec<hidl_string> result;
336 result.resize(2);
337
338 result[0] = "Hello";
339 result[1] = "World";
340
341 _cb(result);
342
343 return Status::ok();
344}
345
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700346Status Bar::thisIsNew() {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700347 ALOGI("SERVER(Bar) thisIsNew");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700348
349 return Status::ok();
350}
351
Steven Moreland88ca4512016-08-11 11:24:10 -0700352template<typename I>
353static std::string arraylikeToString(const I data, size_t size) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700354 std::string out = "[";
355 for (size_t i = 0; i < size; ++i) {
356 if (i > 0) {
357 out += ", ";
358 }
359
360 out += ::android::String8::format("%d", data[i]).string();
361 }
362 out += "]";
363
364 return out;
365}
366
Yifan Hong1dc87932016-08-19 09:51:01 -0700367
Andreas Huber9cd48d02016-08-03 14:25:59 -0700368static std::string vecToString(const hidl_vec<int32_t> &vec) {
Steven Moreland88ca4512016-08-11 11:24:10 -0700369 return arraylikeToString(vec, vec.size());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700370}
371
Yifan Hong1dc87932016-08-19 09:51:01 -0700372static inline void EXPECT_OK(::android::hardware::Status status) {
373 EXPECT_TRUE(status.isOk());
374}
375
376template<typename T, typename S>
377static inline bool EXPECT_ARRAYEQ(const T arr1, const S arr2, size_t size) {
378 for(size_t i = 0; i < size; i++)
379 if(arr1[i] != arr2[i])
380 return false;
381 return true;
382}
383
384
385template <class T>
386static void startServer(T server, const android::hardware::hidl_version kVersion,
387 const char *serviceName,
388 const char *tag) {
Andreas Huber8a82ff72016-08-04 10:29:39 -0700389 using namespace android::hardware;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700390 using android::String16;
Yifan Hong1dc87932016-08-19 09:51:01 -0700391 ALOGI("SERVER(%s) registering", tag);
Steven Moreland40786312016-08-16 10:29:40 -0700392 server->registerAsService(String16(serviceName), kVersion);
Yifan Hong1dc87932016-08-19 09:51:01 -0700393 ALOGI("SERVER(%s) starting", tag);
394 ProcessState::self()->setThreadPoolMaxThreadCount(0);
395 ProcessState::self()->startThreadPool();
396 IPCThreadState::self()->joinThreadPool(); // never ends. needs kill().
397 ALOGI("SERVER(%s) ends.", tag);
398}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700399
Andreas Huber9cd48d02016-08-03 14:25:59 -0700400
Yifan Hong1dc87932016-08-19 09:51:01 -0700401class HidlTest : public ::testing::Test {
402public:
403 sp<::android::hardware::IBinder> service;
404 sp<IFoo> foo;
405 sp<IBar> bar;
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700406 sp<IFooCallback> fooCb;
Yifan Hong1dc87932016-08-19 09:51:01 -0700407 sp<::android::hardware::IBinder> cbService;
408 virtual void SetUp() override {
409 ALOGI("Test setup beginning...");
410 using namespace android::hardware;
411 using android::String16;
412 const hidl_version kVersion = make_hidl_version(1, 0);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700413
Steven Moreland40786312016-08-16 10:29:40 -0700414 foo = IFoo::getService(String16("foo"), kVersion);
Yifan Hong1dc87932016-08-19 09:51:01 -0700415 CHECK(foo != NULL);
416
Steven Moreland40786312016-08-16 10:29:40 -0700417 bar = IBar::getService(String16("foo"), kVersion);
Yifan Hong1dc87932016-08-19 09:51:01 -0700418 CHECK(bar != NULL);
419
Steven Moreland40786312016-08-16 10:29:40 -0700420 fooCb = IFooCallback::getService(String16("foo callback"), kVersion);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700421 CHECK(fooCb != NULL);
422
Yifan Hong1dc87932016-08-19 09:51:01 -0700423 ALOGI("Test setup complete");
424 }
425 virtual void TearDown() override {
426 }
427};
428
429class HidlEnvironment : public ::testing::Environment {
430private:
431 pid_t fooCallbackServerPid, barServerPid;
432public:
433 virtual void SetUp() {
434 ALOGI("Environment setup beginning...");
435 // use fork to create and kill to destroy server processes.
436 if ((barServerPid = fork()) == 0) {
437 // Fear me, I am a child.
438 startServer(new Bar, android::hardware::make_hidl_version(1, 0),
439 "foo", "Bar"); // never returns
440 return;
441 }
442
443 if ((fooCallbackServerPid = fork()) == 0) {
444 // Fear me, I am a second child.
445 startServer(new FooCallback, android::hardware::make_hidl_version(1, 0),
446 "foo callback", "FooCalback"); // never returns
447 return;
448 }
449
450 // Fear you not, I am parent.
451 sleep(1);
452 ALOGI("Environment setup complete.");
453 }
454
455 virtual void TearDown() {
456 // clean up by killing server processes.
457 ALOGI("Environment tear-down beginning...");
458 ALOGI("Killing servers...");
459 if(kill(barServerPid, SIGTERM)) {
460 ALOGE("Could not kill barServer; errno = %d", errno);
461 } else {
462 int status;
463 ALOGI("Waiting for barServer to exit...");
464 waitpid(barServerPid, &status, 0);
465 ALOGI("Continuing...");
466 }
467 if(kill(fooCallbackServerPid, SIGTERM)) {
468 ALOGE("Could not kill fooCallbackServer; errno = %d", errno);
469 } else {
470 int status;
471 ALOGI("Waiting for fooCallbackServer to exit...");
472 waitpid(barServerPid, &status, 0);
473 ALOGI("Continuing...");
474 }
475 ALOGI("Servers all killed.");
476 ALOGI("Environment tear-down complete.");
477 }
478};
479
480TEST_F(HidlTest, FooDoThisTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700481 ALOGI("CLIENT call doThis.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700482 EXPECT_OK(foo->doThis(1.0f));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700483 ALOGI("CLIENT doThis returned.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700484 EXPECT_EQ(true, true);
Yifan Hong1dc87932016-08-19 09:51:01 -0700485}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700486
Yifan Hong1dc87932016-08-19 09:51:01 -0700487TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700488 ALOGI("CLIENT call doThatAndReturnSomething.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700489 int32_t result = foo->doThatAndReturnSomething(2.0f);
490 ALOGI("CLIENT doThatAndReturnSomething returned %d.", result);
Yifan Hong1dc87932016-08-19 09:51:01 -0700491 EXPECT_EQ(result, 666);
492}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700493
Yifan Hong1dc87932016-08-19 09:51:01 -0700494TEST_F(HidlTest, FooDoQuiteABitTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700495 ALOGI("CLIENT call doQuiteABit");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700496 double something = foo->doQuiteABit(1, 2, 3.0f, 4.0);
497 ALOGI("CLIENT doQuiteABit returned %f.", something);
Yifan Hong1dc87932016-08-19 09:51:01 -0700498 EXPECT_DOUBLE_EQ(something, 666.5);
499}
500
501TEST_F(HidlTest, FooDoSomethingElseTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700502
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700503 ALOGI("CLIENT call doSomethingElse");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700504 int32_t param[15];
505 for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) {
506 param[i] = i;
507 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700508 EXPECT_OK(foo->doSomethingElse(param, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700509 ALOGI("CLIENT doSomethingElse returned %s.",
Steven Moreland88ca4512016-08-11 11:24:10 -0700510 arraylikeToString(something, 32).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700511 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
512 26, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2};
513 EXPECT_ARRAYEQ(something, expect, 32);
514 }));
515}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700516
Yifan Hong1dc87932016-08-19 09:51:01 -0700517TEST_F(HidlTest, FooDoStuffAndReturnAStringTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700518 ALOGI("CLIENT call doStuffAndReturnAString");
Yifan Hong1dc87932016-08-19 09:51:01 -0700519 EXPECT_OK(foo->doStuffAndReturnAString([&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700520 ALOGI("CLIENT doStuffAndReturnAString returned '%s'.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700521 something.c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700522 EXPECT_STREQ(something.c_str(), "Hello, world");
523 }));
524}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700525
Yifan Hong1dc87932016-08-19 09:51:01 -0700526TEST_F(HidlTest, FooMapThisVectorTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700527 hidl_vec<int32_t> vecParam;
528 vecParam.resize(10);
529 for (size_t i = 0; i < 10; ++i) {
530 vecParam[i] = i;
531 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700532 EXPECT_OK(foo->mapThisVector(vecParam, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700533 ALOGI("CLIENT mapThisVector returned %s.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700534 vecToString(something).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700535 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18};
536 EXPECT_ARRAYEQ(something, expect, something.size());
537 }));
538}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700539
Yifan Hong1dc87932016-08-19 09:51:01 -0700540TEST_F(HidlTest, FooCallMeTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700541 ALOGI("CLIENT call callMe.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700542 // callMe is oneway, should return instantly.
543 nsecs_t now;
544 now = systemTime();
545 EXPECT_OK(foo->callMe(fooCb));
546 EXPECT_TRUE(systemTime() - now < FooCallback::ONEWAY_TOLERANCE_NS);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700547 ALOGI("CLIENT callMe returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700548}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700549
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700550TEST_F(HidlTest, ForReportResultsTest) {
551
552 // Bar::callMe will invoke three methods on FooCallback; one will return
553 // right away (even though it is a two-way method); the second one will
554 // block Bar for FooCallback::DELAY_S seconds, and the third one will return
555 // to Bar right away (is oneway) but will itself block for DELAY_S seconds.
556 // We need a way to make sure that these three things have happened within
557 // 2*DELAY_S seconds plus some small tolerance.
558 //
559 // Method FooCallback::reportResults() takes a timeout parameter. It blocks for
560 // that length of time, while waiting for the three methods above to
561 // complete. It returns the information of whether each method was invoked,
562 // as well as how long the body of the method took to execute. We verify
563 // the information returned by reportResults() against the timeout we pass (which
564 // is long enough for the method bodies to execute, plus tolerance), and
565 // verify that eachof them executed, as expected, and took the length of
566 // time to execute that we also expect.
567
568 const nsecs_t reportResultsNs =
Andreas Huber03866f52016-08-30 14:19:52 -0700569 2 * FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS;
570
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700571 ALOGI("CLIENT: Waiting for up to %" PRId64 " seconds.",
572 nanoseconds_to_seconds(reportResultsNs));
573
574 fooCb->reportResults(reportResultsNs,
575 [&](int64_t timeLeftNs,
576 const IFooCallback::InvokeInfo invokeResults[3]) {
577 ALOGI("CLIENT: FooCallback::reportResults() is returning data.");
578 ALOGI("CLIENT: Waited for %" PRId64 " milliseconds.",
579 nanoseconds_to_milliseconds(reportResultsNs - timeLeftNs));
580
581 EXPECT_TRUE(0 <= timeLeftNs && timeLeftNs <= reportResultsNs);
582
583 // two-way method, was supposed to return right away
584 EXPECT_TRUE(invokeResults[0].invoked);
585 EXPECT_TRUE(invokeResults[0].timeNs <= invokeResults[0].callerBlockedNs);
586 EXPECT_TRUE(invokeResults[0].callerBlockedNs <= FooCallback::TOLERANCE_NS);
587 // two-way method, was supposed to block caller for DELAY_NS
588 EXPECT_TRUE(invokeResults[1].invoked);
589 EXPECT_TRUE(invokeResults[1].timeNs <= invokeResults[1].callerBlockedNs);
590 EXPECT_TRUE(invokeResults[1].callerBlockedNs <=
591 FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
592 // one-way method, do not block caller, but body was supposed to block for DELAY_NS
593 EXPECT_TRUE(invokeResults[2].invoked);
594 EXPECT_TRUE(invokeResults[2].callerBlockedNs <= FooCallback::ONEWAY_TOLERANCE_NS);
595 EXPECT_TRUE(invokeResults[2].timeNs <= FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
596 });
597}
598
599
600
Yifan Hong1dc87932016-08-19 09:51:01 -0700601TEST_F(HidlTest, FooUseAnEnumTest) {
602 ALOGI("CLIENT call useAnEnum.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700603 IFoo::SomeEnum sleepy = foo->useAnEnum(IFoo::SomeEnum::quux);
604 ALOGI("CLIENT useAnEnum returned %u", (unsigned)sleepy);
Yifan Hong1dc87932016-08-19 09:51:01 -0700605 EXPECT_EQ(sleepy, IFoo::SomeEnum::goober);
606}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700607
Yifan Hong1dc87932016-08-19 09:51:01 -0700608TEST_F(HidlTest, FooHaveAGooberTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700609 hidl_vec<IFoo::Goober> gooberVecParam;
610 gooberVecParam.resize(2);
611 gooberVecParam[0].name = "Hello";
612 gooberVecParam[1].name = "World";
613
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700614 ALOGI("CLIENT call haveAGooberVec.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700615 EXPECT_OK(foo->haveAGooberVec(gooberVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700616 ALOGI("CLIENT haveAGooberVec returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700617
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700618 ALOGI("CLIENT call haveaGoober.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700619 EXPECT_OK(foo->haveAGoober(gooberVecParam[0]));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700620 ALOGI("CLIENT haveaGoober returned.");
621
622 ALOGI("CLIENT call haveAGooberArray.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700623 IFoo::Goober gooberArrayParam[20];
Yifan Hong1dc87932016-08-19 09:51:01 -0700624 EXPECT_OK(foo->haveAGooberArray(gooberArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700625 ALOGI("CLIENT haveAGooberArray returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700626}
Steven Moreland88ca4512016-08-11 11:24:10 -0700627
Yifan Hong1dc87932016-08-19 09:51:01 -0700628TEST_F(HidlTest, FooHaveATypeFromAnotherFileTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700629 ALOGI("CLIENT call haveATypeFromAnotherFile.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700630 Abc abcParam{};
631 abcParam.x = "alphabet";
632 abcParam.y = 3.14f;
633 abcParam.z = new native_handle_t();
Yifan Hong1dc87932016-08-19 09:51:01 -0700634 EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700635 ALOGI("CLIENT haveATypeFromAnotherFile returned.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700636 delete abcParam.z;
637 abcParam.z = NULL;
Yifan Hong1dc87932016-08-19 09:51:01 -0700638}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700639
Yifan Hong1dc87932016-08-19 09:51:01 -0700640TEST_F(HidlTest, FooHaveSomeStringsTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700641 ALOGI("CLIENT call haveSomeStrings.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700642 hidl_string stringArrayParam[3];
643 stringArrayParam[0] = "What";
644 stringArrayParam[1] = "a";
645 stringArrayParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700646 EXPECT_OK(foo->haveSomeStrings(stringArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700647 ALOGI("CLIENT haveSomeStrings returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700648}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700649
Yifan Hong1dc87932016-08-19 09:51:01 -0700650TEST_F(HidlTest, FooHaveAStringVecTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700651 ALOGI("CLIENT call haveAStringVec.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700652 hidl_vec<hidl_string> stringVecParam;
653 stringVecParam.resize(3);
654 stringVecParam[0] = "What";
655 stringVecParam[1] = "a";
656 stringVecParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700657 EXPECT_OK(foo->haveAStringVec(stringVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700658 ALOGI("CLIENT haveAStringVec returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700659}
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700660
Yifan Hong1dc87932016-08-19 09:51:01 -0700661TEST_F(HidlTest, BarThisIsNewTest) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700662 // Now the tricky part, get access to the derived interface.
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700663 ALOGI("CLIENT call thisIsNew.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700664 EXPECT_OK(bar->thisIsNew());
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700665 ALOGI("CLIENT thisIsNew returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700666}
667
Yifan Hong1dc87932016-08-19 09:51:01 -0700668int main(int argc, char **argv) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700669
Yifan Hong1dc87932016-08-19 09:51:01 -0700670 ::testing::AddGlobalTestEnvironment(new HidlEnvironment);
671 ::testing::InitGoogleTest(&argc, argv);
672 int status = RUN_ALL_TESTS();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700673
Yifan Hong1dc87932016-08-19 09:51:01 -0700674 ALOGI("Test result = %d", status);
675 return status;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700676}