blob: 72ec8cd3234aa2c157226272d2c2ff741c429ea7 [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>
Andreas Huber9cd48d02016-08-03 14:25:59 -070020#include <hwbinder/IPCThreadState.h>
Andreas Huber9cd48d02016-08-03 14:25:59 -070021#include <hwbinder/ProcessState.h>
22#include <hwbinder/Status.h>
23
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;
33using ::android::hardware::tests::foo::V1_0::Abc;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -070034using ::android::hardware::Return;
Andreas Huber8a82ff72016-08-04 10:29:39 -070035using ::android::hardware::Status;
36using ::android::hardware::hidl_vec;
37using ::android::hardware::hidl_string;
Andreas Huber9cd48d02016-08-03 14:25:59 -070038using ::android::sp;
Iliyan Malchev0acf4192016-08-22 19:33:20 -070039using ::android::Mutex;
40using ::android::Condition;
Andreas Huber9cd48d02016-08-03 14:25:59 -070041
42struct FooCallback : public BnFooCallback {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070043 FooCallback() : invokeInfo{}, mLock{}, mCond{} {}
Iliyan Malchevd856b052016-08-16 22:25:27 -070044 Status heyItsYou(const sp<IFooCallback> &cb) override;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -070045 Return<bool> heyItsYouIsntIt(const sp<IFooCallback> &cb) override;
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070046 Status heyItsTheMeaningOfLife(uint8_t tmol) override;
Iliyan Malchev0acf4192016-08-22 19:33:20 -070047 Status reportResults(int64_t ns, reportResults_cb cb) override;
48 Status youBlockedMeFor(const int64_t ns[3]) override;
49
50 static constexpr nsecs_t DELAY_S = 5;
51 static constexpr nsecs_t DELAY_NS = seconds_to_nanoseconds(DELAY_S);
52 static constexpr nsecs_t TOLERANCE_NS = milliseconds_to_nanoseconds(10);
53 static constexpr nsecs_t ONEWAY_TOLERANCE_NS = milliseconds_to_nanoseconds(1);
54
55 InvokeInfo invokeInfo[3];
56 Mutex mLock;
57 Condition mCond;
Andreas Huber9cd48d02016-08-03 14:25:59 -070058};
59
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070060Status FooCallback::heyItsYou(
61 const sp<IFooCallback> &_cb) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070062 nsecs_t start = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070063 ALOGI("SERVER(FooCallback) heyItsYou cb = %p", _cb.get());
Iliyan Malchev0acf4192016-08-22 19:33:20 -070064 mLock.lock();
65 invokeInfo[0].invoked = true;
66 invokeInfo[0].timeNs = systemTime() - start;
67 mCond.signal();
68 mLock.unlock();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070069 return Status::ok();
70}
Andreas Huber9cd48d02016-08-03 14:25:59 -070071
Iliyan Malchev2b6591b2016-08-18 19:15:19 -070072Return<bool> FooCallback::heyItsYouIsntIt(const sp<IFooCallback> &_cb) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070073 nsecs_t start = systemTime();
74 ALOGI("SERVER(FooCallback) heyItsYouIsntIt cb = %p sleeping for %" PRId64 " seconds", _cb.get(), DELAY_S);
75 sleep(DELAY_S);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070076 ALOGI("SERVER(FooCallback) heyItsYouIsntIt cb = %p responding", _cb.get());
Iliyan Malchev0acf4192016-08-22 19:33:20 -070077 mLock.lock();
78 invokeInfo[1].invoked = true;
79 invokeInfo[1].timeNs = systemTime() - start;
80 mCond.signal();
81 mLock.unlock();
Iliyan Malchevd856b052016-08-16 22:25:27 -070082 return true;
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070083}
84
85Status FooCallback::heyItsTheMeaningOfLife(uint8_t tmol) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -070086 nsecs_t start = systemTime();
87 ALOGI("SERVER(FooCallback) heyItsTheMeaningOfLife = %d sleeping for %" PRId64 " seconds", tmol, DELAY_S);
88 sleep(DELAY_S);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070089 ALOGI("SERVER(FooCallback) heyItsTheMeaningOfLife = %d done sleeping", tmol);
Iliyan Malchev0acf4192016-08-22 19:33:20 -070090 mLock.lock();
91 invokeInfo[2].invoked = true;
92 invokeInfo[2].timeNs = systemTime() - start;
93 mCond.signal();
94 mLock.unlock();
95 return Status::ok();
96}
97
98Status FooCallback::reportResults(int64_t ns, reportResults_cb cb) {
99 ALOGI("SERVER(FooCallback) reportResults(%" PRId64 ") seconds", nanoseconds_to_seconds(ns));
100 nsecs_t leftToWaitNs = ns;
101 mLock.lock();
102 while (!(invokeInfo[0].invoked && invokeInfo[1].invoked && invokeInfo[2].invoked) &&
103 leftToWaitNs > 0) {
104 nsecs_t start = systemTime();
105 ::android::status_t rc = mCond.waitRelative(mLock, leftToWaitNs);
106 if (rc != ::android::OK) {
107 ALOGI("SERVER(FooCallback)::reportResults(%" PRId64 ") Condition::waitRelative(%" PRId64 ") returned error (%d)", ns, leftToWaitNs, rc);
108 break;
109 }
110 ALOGI("SERVER(FooCallback)::reportResults(%" PRId64 ") Condition::waitRelative was signalled", ns);
111 leftToWaitNs -= systemTime() - start;
112 }
113 mLock.unlock();
114 cb(leftToWaitNs, invokeInfo);
115 return Status::ok();
116}
117
118Status FooCallback::youBlockedMeFor(const int64_t ns[3]) {
119 for (size_t i = 0; i < 3; i++) {
120 invokeInfo[i].callerBlockedNs = ns[i];
121 }
Andreas Huber9cd48d02016-08-03 14:25:59 -0700122 return Status::ok();
123}
124
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700125struct Bar : public BnBar {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700126 Status doThis(float param) override;
127
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700128 Return<int32_t> doThatAndReturnSomething(int64_t param) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700129
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700130 Return<double> doQuiteABit(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700131 int32_t a,
132 int64_t b,
133 float c,
Iliyan Malchevd856b052016-08-16 22:25:27 -0700134 double d) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700135
136 Status doSomethingElse(
137 const int32_t param[15], doSomethingElse_cb _cb) override;
138
139 Status doStuffAndReturnAString(
140 doStuffAndReturnAString_cb _cb) override;
141
142 Status mapThisVector(
143 const hidl_vec<int32_t> &param, mapThisVector_cb _cb) override;
144
145 Status callMe(
146 const sp<IFooCallback> &cb) override;
147
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700148 Return<SomeEnum> useAnEnum(SomeEnum param) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700149
Steven Moreland88ca4512016-08-11 11:24:10 -0700150 Status haveAGooberVec(const hidl_vec<Goober>& param) override;
151 Status haveAGoober(const Goober &g) override;
152 Status haveAGooberArray(const Goober lots[20]) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700153
Steven Moreland88ca4512016-08-11 11:24:10 -0700154 Status haveATypeFromAnotherFile(const Abc &def) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700155
156 Status haveSomeStrings(
157 const hidl_string array[3],
158 haveSomeStrings_cb _cb) override;
159
160 Status haveAStringVec(
161 const hidl_vec<hidl_string> &vector,
162 haveAStringVec_cb _cb) override;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700163
164 Status thisIsNew() override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700165};
166
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700167Status Bar::doThis(float param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700168 ALOGI("SERVER(Bar) doThis(%.2f)", param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700169
170 return Status::ok();
171}
172
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700173Return<int32_t> Bar::doThatAndReturnSomething(
Iliyan Malchevd856b052016-08-16 22:25:27 -0700174 int64_t param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700175 ALOGI("SERVER(Bar) doThatAndReturnSomething(%ld)", param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700176
Iliyan Malchevd856b052016-08-16 22:25:27 -0700177 return 666;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700178}
179
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700180Return<double> Bar::doQuiteABit(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700181 int32_t a,
182 int64_t b,
183 float c,
Iliyan Malchevd856b052016-08-16 22:25:27 -0700184 double d) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700185 ALOGI("SERVER(Bar) doQuiteABit(%d, %ld, %.2f, %.2f)", a, b, c, d);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700186
Iliyan Malchevd856b052016-08-16 22:25:27 -0700187 return 666.5;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700188}
189
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700190Status Bar::doSomethingElse(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700191 const int32_t param[15], doSomethingElse_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700192 ALOGI("SERVER(Bar) doSomethingElse(...)");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700193
194 int32_t result[32] = { 0 };
195 for (size_t i = 0; i < 15; ++i) {
196 result[i] = 2 * param[i];
197 result[15 + i] = param[i];
198 }
199 result[30] = 1;
200 result[31] = 2;
201
202 _cb(result);
203
204 return Status::ok();
205}
206
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700207Status Bar::doStuffAndReturnAString(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700208 doStuffAndReturnAString_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700209 ALOGI("SERVER(Bar) doStuffAndReturnAString");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700210
211 hidl_string s;
212 s = "Hello, world";
213
214 _cb(s);
215
216 return Status::ok();
217}
218
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700219Status Bar::mapThisVector(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700220 const hidl_vec<int32_t> &param, mapThisVector_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700221 ALOGI("SERVER(Bar) mapThisVector");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700222
223 hidl_vec<int32_t> out;
Andreas Huber899b0632016-08-15 12:21:19 -0700224 out.resize(param.size());
Steven Moreland88ca4512016-08-11 11:24:10 -0700225
226 for (size_t i = 0; i < out.size(); ++i) {
227 out[i] = param[i] * 2;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700228 }
229
230 _cb(out);
231
Andreas Huber9cd48d02016-08-03 14:25:59 -0700232 return Status::ok();
233}
234
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700235Status Bar::callMe(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700236 const sp<IFooCallback> &cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700237 ALOGI("SERVER(Bar) callMe %p", cb.get());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700238
239 if (cb != NULL) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700240
241 nsecs_t c[3];
242 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYou, " \
243 "should return immediately", cb.get());
244 c[0] = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700245 cb->heyItsYou(cb);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700246 c[0] = systemTime() - c[0];
247 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYou " \
248 "returned after %" PRId64 "ns", cb.get(), c[0]);
249
250 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYouIsntIt, " \
251 "should block for %" PRId64 " seconds", cb.get(),
252 FooCallback::DELAY_S);
253 c[1] = systemTime();
Iliyan Malchevd856b052016-08-16 22:25:27 -0700254 bool answer = cb->heyItsYouIsntIt(cb);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700255 c[1] = systemTime() - c[1];
256 ALOGI("SERVER(Bar) callMe %p IFooCallback::heyItsYouIsntIt " \
257 "responded with %d after %" PRId64 "ns", cb.get(), answer, c[1]);
258
259 ALOGI("SERVER(Bar) callMe %p calling " \
260 "IFooCallback::heyItsTheMeaningOfLife, " \
261 "should return immediately ", cb.get());
262 c[2] = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700263 cb->heyItsTheMeaningOfLife(42);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700264 c[2] = systemTime() - c[2];
265 ALOGI("SERVER(Bar) callMe %p After call to " \
266 "IFooCallback::heyItsTheMeaningOfLife " \
267 "responded after %" PRId64 "ns", cb.get(), c[2]);
268
269 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::youBlockedMeFor " \
270 "to report times", cb.get());
271 cb->youBlockedMeFor(c);
272 ALOGI("SERVER(Bar) callMe %p After call to " \
273 "IFooCallback::heyYouBlockedMeFor", cb.get());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700274 }
275
276 return Status::ok();
277}
278
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700279Return<Bar::SomeEnum> Bar::useAnEnum(SomeEnum param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700280 ALOGI("SERVER(Bar) useAnEnum %d", (int)param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700281
Iliyan Malchevd856b052016-08-16 22:25:27 -0700282 return SomeEnum::goober;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700283}
284
Steven Moreland88ca4512016-08-11 11:24:10 -0700285Status Bar::haveAGooberVec(const hidl_vec<Goober>& param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700286 ALOGI("SERVER(Bar) haveAGooberVec &param = %p", &param);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700287
288 return Status::ok();
289}
290
Steven Moreland88ca4512016-08-11 11:24:10 -0700291Status Bar::haveAGoober(const Goober &g) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700292 ALOGI("SERVER(Bar) haveaGoober g=%p", &g);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700293
294 return Status::ok();
295}
296
Steven Moreland88ca4512016-08-11 11:24:10 -0700297Status Bar::haveAGooberArray(const Goober lots[20]) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700298 ALOGI("SERVER(Bar) haveAGooberArray lots = %p", lots);
Steven Moreland88ca4512016-08-11 11:24:10 -0700299
300 return Status::ok();
301}
302
303Status Bar::haveATypeFromAnotherFile(const Abc &def) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700304 ALOGI("SERVER(Bar) haveATypeFromAnotherFile def=%p", &def);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700305
306 return Status::ok();
307}
308
309Status Bar::haveSomeStrings(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700310 const hidl_string array[3],
311 haveSomeStrings_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700312 ALOGI("SERVER(Bar) haveSomeStrings([\"%s\", \"%s\", \"%s\"])",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700313 array[0].c_str(),
314 array[1].c_str(),
315 array[2].c_str());
316
317 hidl_string result[2];
318 result[0] = "Hello";
319 result[1] = "World";
320
321 _cb(result);
322
323 return Status::ok();
324}
325
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700326Status Bar::haveAStringVec(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700327 const hidl_vec<hidl_string> &vector,
328 haveAStringVec_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700329 ALOGI("SERVER(Bar) haveAStringVec([\"%s\", \"%s\", \"%s\"])",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700330 vector[0].c_str(),
331 vector[1].c_str(),
332 vector[2].c_str());
333
334 hidl_vec<hidl_string> result;
335 result.resize(2);
336
337 result[0] = "Hello";
338 result[1] = "World";
339
340 _cb(result);
341
342 return Status::ok();
343}
344
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700345Status Bar::thisIsNew() {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700346 ALOGI("SERVER(Bar) thisIsNew");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700347
348 return Status::ok();
349}
350
Steven Moreland88ca4512016-08-11 11:24:10 -0700351template<typename I>
352static std::string arraylikeToString(const I data, size_t size) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700353 std::string out = "[";
354 for (size_t i = 0; i < size; ++i) {
355 if (i > 0) {
356 out += ", ";
357 }
358
359 out += ::android::String8::format("%d", data[i]).string();
360 }
361 out += "]";
362
363 return out;
364}
365
Yifan Hong1dc87932016-08-19 09:51:01 -0700366
Andreas Huber9cd48d02016-08-03 14:25:59 -0700367static std::string vecToString(const hidl_vec<int32_t> &vec) {
Steven Moreland88ca4512016-08-11 11:24:10 -0700368 return arraylikeToString(vec, vec.size());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700369}
370
Yifan Hong1dc87932016-08-19 09:51:01 -0700371static inline void EXPECT_OK(::android::hardware::Status status) {
372 EXPECT_TRUE(status.isOk());
373}
374
375template<typename T, typename S>
376static inline bool EXPECT_ARRAYEQ(const T arr1, const S arr2, size_t size) {
377 for(size_t i = 0; i < size; i++)
378 if(arr1[i] != arr2[i])
379 return false;
380 return true;
381}
382
383
384template <class T>
385static void startServer(T server, const android::hardware::hidl_version kVersion,
386 const char *serviceName,
387 const char *tag) {
Andreas Huber8a82ff72016-08-04 10:29:39 -0700388 using namespace android::hardware;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700389 using android::String16;
Yifan Hong1dc87932016-08-19 09:51:01 -0700390 ALOGI("SERVER(%s) registering", tag);
391 defaultServiceManager()->addService(String16(serviceName), server, kVersion);
392 ALOGI("SERVER(%s) starting", tag);
393 ProcessState::self()->setThreadPoolMaxThreadCount(0);
394 ProcessState::self()->startThreadPool();
395 IPCThreadState::self()->joinThreadPool(); // never ends. needs kill().
396 ALOGI("SERVER(%s) ends.", tag);
397}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700398
Andreas Huber9cd48d02016-08-03 14:25:59 -0700399
Yifan Hong1dc87932016-08-19 09:51:01 -0700400class HidlTest : public ::testing::Test {
401public:
402 sp<::android::hardware::IBinder> service;
403 sp<IFoo> foo;
404 sp<IBar> bar;
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700405 sp<IFooCallback> fooCb;
Yifan Hong1dc87932016-08-19 09:51:01 -0700406 sp<::android::hardware::IBinder> cbService;
407 virtual void SetUp() override {
408 ALOGI("Test setup beginning...");
409 using namespace android::hardware;
410 using android::String16;
411 const hidl_version kVersion = make_hidl_version(1, 0);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700412
Yifan Hong1dc87932016-08-19 09:51:01 -0700413 service =
414 defaultServiceManager()->getService(String16("foo"), kVersion);
415 ALOGI("CLIENT Found service foo.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700416
Yifan Hong1dc87932016-08-19 09:51:01 -0700417 CHECK(service != NULL);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700418
Yifan Hong1dc87932016-08-19 09:51:01 -0700419 foo = IFoo::asInterface(service);
420 CHECK(foo != NULL);
421
422 bar = IBar::asInterface(service);
423 CHECK(bar != NULL);
424
425 cbService = defaultServiceManager()->getService(String16("foo callback"), kVersion);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700426 CHECK(cbService != NULL);
427
428 fooCb = IFooCallback::asInterface(cbService);
429 CHECK(fooCb != NULL);
430
Yifan Hong1dc87932016-08-19 09:51:01 -0700431 ALOGI("Test setup complete");
432 }
433 virtual void TearDown() override {
434 }
435};
436
437class HidlEnvironment : public ::testing::Environment {
438private:
439 pid_t fooCallbackServerPid, barServerPid;
440public:
441 virtual void SetUp() {
442 ALOGI("Environment setup beginning...");
443 // use fork to create and kill to destroy server processes.
444 if ((barServerPid = fork()) == 0) {
445 // Fear me, I am a child.
446 startServer(new Bar, android::hardware::make_hidl_version(1, 0),
447 "foo", "Bar"); // never returns
448 return;
449 }
450
451 if ((fooCallbackServerPid = fork()) == 0) {
452 // Fear me, I am a second child.
453 startServer(new FooCallback, android::hardware::make_hidl_version(1, 0),
454 "foo callback", "FooCalback"); // never returns
455 return;
456 }
457
458 // Fear you not, I am parent.
459 sleep(1);
460 ALOGI("Environment setup complete.");
461 }
462
463 virtual void TearDown() {
464 // clean up by killing server processes.
465 ALOGI("Environment tear-down beginning...");
466 ALOGI("Killing servers...");
467 if(kill(barServerPid, SIGTERM)) {
468 ALOGE("Could not kill barServer; errno = %d", errno);
469 } else {
470 int status;
471 ALOGI("Waiting for barServer to exit...");
472 waitpid(barServerPid, &status, 0);
473 ALOGI("Continuing...");
474 }
475 if(kill(fooCallbackServerPid, SIGTERM)) {
476 ALOGE("Could not kill fooCallbackServer; errno = %d", errno);
477 } else {
478 int status;
479 ALOGI("Waiting for fooCallbackServer to exit...");
480 waitpid(barServerPid, &status, 0);
481 ALOGI("Continuing...");
482 }
483 ALOGI("Servers all killed.");
484 ALOGI("Environment tear-down complete.");
485 }
486};
487
488TEST_F(HidlTest, FooDoThisTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700489 ALOGI("CLIENT call doThis.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700490 EXPECT_OK(foo->doThis(1.0f));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700491 ALOGI("CLIENT doThis returned.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700492 EXPECT_EQ(true, true);
Yifan Hong1dc87932016-08-19 09:51:01 -0700493}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700494
Yifan Hong1dc87932016-08-19 09:51:01 -0700495TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700496 ALOGI("CLIENT call doThatAndReturnSomething.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700497 int32_t result = foo->doThatAndReturnSomething(2.0f);
498 ALOGI("CLIENT doThatAndReturnSomething returned %d.", result);
Yifan Hong1dc87932016-08-19 09:51:01 -0700499 EXPECT_EQ(result, 666);
500}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700501
Yifan Hong1dc87932016-08-19 09:51:01 -0700502TEST_F(HidlTest, FooDoQuiteABitTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700503 ALOGI("CLIENT call doQuiteABit");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700504 double something = foo->doQuiteABit(1, 2, 3.0f, 4.0);
505 ALOGI("CLIENT doQuiteABit returned %f.", something);
Yifan Hong1dc87932016-08-19 09:51:01 -0700506 EXPECT_DOUBLE_EQ(something, 666.5);
507}
508
509TEST_F(HidlTest, FooDoSomethingElseTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700510
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700511 ALOGI("CLIENT call doSomethingElse");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700512 int32_t param[15];
513 for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) {
514 param[i] = i;
515 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700516 EXPECT_OK(foo->doSomethingElse(param, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700517 ALOGI("CLIENT doSomethingElse returned %s.",
Steven Moreland88ca4512016-08-11 11:24:10 -0700518 arraylikeToString(something, 32).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700519 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
520 26, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2};
521 EXPECT_ARRAYEQ(something, expect, 32);
522 }));
523}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700524
Yifan Hong1dc87932016-08-19 09:51:01 -0700525TEST_F(HidlTest, FooDoStuffAndReturnAStringTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700526 ALOGI("CLIENT call doStuffAndReturnAString");
Yifan Hong1dc87932016-08-19 09:51:01 -0700527 EXPECT_OK(foo->doStuffAndReturnAString([&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700528 ALOGI("CLIENT doStuffAndReturnAString returned '%s'.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700529 something.c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700530 EXPECT_STREQ(something.c_str(), "Hello, world");
531 }));
532}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700533
Yifan Hong1dc87932016-08-19 09:51:01 -0700534TEST_F(HidlTest, FooMapThisVectorTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700535 hidl_vec<int32_t> vecParam;
536 vecParam.resize(10);
537 for (size_t i = 0; i < 10; ++i) {
538 vecParam[i] = i;
539 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700540 EXPECT_OK(foo->mapThisVector(vecParam, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700541 ALOGI("CLIENT mapThisVector returned %s.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700542 vecToString(something).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700543 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18};
544 EXPECT_ARRAYEQ(something, expect, something.size());
545 }));
546}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700547
Yifan Hong1dc87932016-08-19 09:51:01 -0700548TEST_F(HidlTest, FooCallMeTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700549 ALOGI("CLIENT call callMe.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700550 // callMe is oneway, should return instantly.
551 nsecs_t now;
552 now = systemTime();
553 EXPECT_OK(foo->callMe(fooCb));
554 EXPECT_TRUE(systemTime() - now < FooCallback::ONEWAY_TOLERANCE_NS);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700555 ALOGI("CLIENT callMe returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700556}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700557
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700558TEST_F(HidlTest, ForReportResultsTest) {
559
560 // Bar::callMe will invoke three methods on FooCallback; one will return
561 // right away (even though it is a two-way method); the second one will
562 // block Bar for FooCallback::DELAY_S seconds, and the third one will return
563 // to Bar right away (is oneway) but will itself block for DELAY_S seconds.
564 // We need a way to make sure that these three things have happened within
565 // 2*DELAY_S seconds plus some small tolerance.
566 //
567 // Method FooCallback::reportResults() takes a timeout parameter. It blocks for
568 // that length of time, while waiting for the three methods above to
569 // complete. It returns the information of whether each method was invoked,
570 // as well as how long the body of the method took to execute. We verify
571 // the information returned by reportResults() against the timeout we pass (which
572 // is long enough for the method bodies to execute, plus tolerance), and
573 // verify that eachof them executed, as expected, and took the length of
574 // time to execute that we also expect.
575
576 const nsecs_t reportResultsNs =
577 seconds_to_nanoseconds(2*(FooCallback::DELAY_S +
578 FooCallback::TOLERANCE_NS));
579 ALOGI("CLIENT: Waiting for up to %" PRId64 " seconds.",
580 nanoseconds_to_seconds(reportResultsNs));
581
582 fooCb->reportResults(reportResultsNs,
583 [&](int64_t timeLeftNs,
584 const IFooCallback::InvokeInfo invokeResults[3]) {
585 ALOGI("CLIENT: FooCallback::reportResults() is returning data.");
586 ALOGI("CLIENT: Waited for %" PRId64 " milliseconds.",
587 nanoseconds_to_milliseconds(reportResultsNs - timeLeftNs));
588
589 EXPECT_TRUE(0 <= timeLeftNs && timeLeftNs <= reportResultsNs);
590
591 // two-way method, was supposed to return right away
592 EXPECT_TRUE(invokeResults[0].invoked);
593 EXPECT_TRUE(invokeResults[0].timeNs <= invokeResults[0].callerBlockedNs);
594 EXPECT_TRUE(invokeResults[0].callerBlockedNs <= FooCallback::TOLERANCE_NS);
595 // two-way method, was supposed to block caller for DELAY_NS
596 EXPECT_TRUE(invokeResults[1].invoked);
597 EXPECT_TRUE(invokeResults[1].timeNs <= invokeResults[1].callerBlockedNs);
598 EXPECT_TRUE(invokeResults[1].callerBlockedNs <=
599 FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
600 // one-way method, do not block caller, but body was supposed to block for DELAY_NS
601 EXPECT_TRUE(invokeResults[2].invoked);
602 EXPECT_TRUE(invokeResults[2].callerBlockedNs <= FooCallback::ONEWAY_TOLERANCE_NS);
603 EXPECT_TRUE(invokeResults[2].timeNs <= FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
604 });
605}
606
607
608
Yifan Hong1dc87932016-08-19 09:51:01 -0700609TEST_F(HidlTest, FooUseAnEnumTest) {
610 ALOGI("CLIENT call useAnEnum.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700611 IFoo::SomeEnum sleepy = foo->useAnEnum(IFoo::SomeEnum::quux);
612 ALOGI("CLIENT useAnEnum returned %u", (unsigned)sleepy);
Yifan Hong1dc87932016-08-19 09:51:01 -0700613 EXPECT_EQ(sleepy, IFoo::SomeEnum::goober);
614}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700615
Yifan Hong1dc87932016-08-19 09:51:01 -0700616TEST_F(HidlTest, FooHaveAGooberTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700617 hidl_vec<IFoo::Goober> gooberVecParam;
618 gooberVecParam.resize(2);
619 gooberVecParam[0].name = "Hello";
620 gooberVecParam[1].name = "World";
621
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700622 ALOGI("CLIENT call haveAGooberVec.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700623 EXPECT_OK(foo->haveAGooberVec(gooberVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700624 ALOGI("CLIENT haveAGooberVec returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700625
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700626 ALOGI("CLIENT call haveaGoober.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700627 EXPECT_OK(foo->haveAGoober(gooberVecParam[0]));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700628 ALOGI("CLIENT haveaGoober returned.");
629
630 ALOGI("CLIENT call haveAGooberArray.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700631 IFoo::Goober gooberArrayParam[20];
Yifan Hong1dc87932016-08-19 09:51:01 -0700632 EXPECT_OK(foo->haveAGooberArray(gooberArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700633 ALOGI("CLIENT haveAGooberArray returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700634}
Steven Moreland88ca4512016-08-11 11:24:10 -0700635
Yifan Hong1dc87932016-08-19 09:51:01 -0700636TEST_F(HidlTest, FooHaveATypeFromAnotherFileTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700637 ALOGI("CLIENT call haveATypeFromAnotherFile.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700638 Abc abcParam{};
639 abcParam.x = "alphabet";
640 abcParam.y = 3.14f;
641 abcParam.z = new native_handle_t();
Yifan Hong1dc87932016-08-19 09:51:01 -0700642 EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700643 ALOGI("CLIENT haveATypeFromAnotherFile returned.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700644 delete abcParam.z;
645 abcParam.z = NULL;
Yifan Hong1dc87932016-08-19 09:51:01 -0700646}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700647
Yifan Hong1dc87932016-08-19 09:51:01 -0700648TEST_F(HidlTest, FooHaveSomeStringsTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700649 ALOGI("CLIENT call haveSomeStrings.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700650 hidl_string stringArrayParam[3];
651 stringArrayParam[0] = "What";
652 stringArrayParam[1] = "a";
653 stringArrayParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700654 EXPECT_OK(foo->haveSomeStrings(stringArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700655 ALOGI("CLIENT haveSomeStrings returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700656}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700657
Yifan Hong1dc87932016-08-19 09:51:01 -0700658TEST_F(HidlTest, FooHaveAStringVecTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700659 ALOGI("CLIENT call haveAStringVec.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700660 hidl_vec<hidl_string> stringVecParam;
661 stringVecParam.resize(3);
662 stringVecParam[0] = "What";
663 stringVecParam[1] = "a";
664 stringVecParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700665 EXPECT_OK(foo->haveAStringVec(stringVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700666 ALOGI("CLIENT haveAStringVec returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700667}
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700668
Yifan Hong1dc87932016-08-19 09:51:01 -0700669TEST_F(HidlTest, BarThisIsNewTest) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700670 // Now the tricky part, get access to the derived interface.
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700671 ALOGI("CLIENT call thisIsNew.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700672 EXPECT_OK(bar->thisIsNew());
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700673 ALOGI("CLIENT thisIsNew returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700674}
675
Yifan Hong1dc87932016-08-19 09:51:01 -0700676int main(int argc, char **argv) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700677
Yifan Hong1dc87932016-08-19 09:51:01 -0700678 ::testing::AddGlobalTestEnvironment(new HidlEnvironment);
679 ::testing::InitGoogleTest(&argc, argv);
680 int status = RUN_ALL_TESTS();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700681
Yifan Hong1dc87932016-08-19 09:51:01 -0700682 ALOGI("Test result = %d", status);
683 return status;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700684}