blob: 2a55b8e414e0b99e6fe5208abc4ee24b8d806817 [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;
Iliyan Malchevd57066f2016-09-08 13:59:38 -070036using ::android::hardware::Void;
Andreas Huber8a82ff72016-08-04 10:29:39 -070037using ::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 Malchevd57066f2016-09-08 13:59:38 -070045 Return<void> heyItsYou(const sp<IFooCallback> &cb) override;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -070046 Return<bool> heyItsYouIsntIt(const sp<IFooCallback> &cb) override;
Iliyan Malchevd57066f2016-09-08 13:59:38 -070047 Return<void> heyItsTheMeaningOfLife(uint8_t tmol) override;
48 Return<void> reportResults(int64_t ns, reportResults_cb cb) override;
49 Return<void> youBlockedMeFor(const int64_t ns[3]) override;
Iliyan Malchev0acf4192016-08-22 19:33:20 -070050
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 Malchevd57066f2016-09-08 13:59:38 -070061Return<void> FooCallback::heyItsYou(
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070062 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 Malchevd57066f2016-09-08 13:59:38 -070070 return Void();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -070071}
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
Iliyan Malchevd57066f2016-09-08 13:59:38 -070086Return<void> 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();
Iliyan Malchevd57066f2016-09-08 13:59:38 -070096 return Void();
Iliyan Malchev0acf4192016-08-22 19:33:20 -070097}
98
Iliyan Malchevd57066f2016-09-08 13:59:38 -070099Return<void> 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);
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700116 return Void();
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700117}
118
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700119Return<void> FooCallback::youBlockedMeFor(const int64_t ns[3]) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700120 for (size_t i = 0; i < 3; i++) {
121 invokeInfo[i].callerBlockedNs = ns[i];
122 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700123 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700124}
125
Steven Moreland40786312016-08-16 10:29:40 -0700126struct Bar : public IBar {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700127 Return<void> doThis(float param) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700128
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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700137 Return<void> doSomethingElse(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700138 const int32_t param[15], doSomethingElse_cb _cb) override;
139
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700140 Return<void> doStuffAndReturnAString(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700141 doStuffAndReturnAString_cb _cb) override;
142
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700143 Return<void> mapThisVector(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700144 const hidl_vec<int32_t> &param, mapThisVector_cb _cb) override;
145
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700146 Return<void> callMe(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700147 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700151 Return<void> haveAGooberVec(const hidl_vec<Goober>& param) override;
152 Return<void> haveAGoober(const Goober &g) override;
153 Return<void> haveAGooberArray(const Goober lots[20]) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700154
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700155 Return<void> haveATypeFromAnotherFile(const Abc &def) override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700156
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700157 Return<void> haveSomeStrings(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700158 const hidl_string array[3],
159 haveSomeStrings_cb _cb) override;
160
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700161 Return<void> haveAStringVec(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700162 const hidl_vec<hidl_string> &vector,
163 haveAStringVec_cb _cb) override;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700164
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700165 Return<void> thisIsNew() override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700166};
167
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700168Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700171 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700172}
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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700191Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700205 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700206}
207
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700208Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700217 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700218}
219
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700220Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700233 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700234}
235
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700236Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700277 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700278}
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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700286Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700289 return Void();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700290}
291
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700292Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700295 return Void();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700296}
297
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700298Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700301 return Void();
Steven Moreland88ca4512016-08-11 11:24:10 -0700302}
303
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700304Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700307 return Void();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700308}
309
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700310Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700324 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700325}
326
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700327Return<void> 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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700343 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700344}
345
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700346Return<void> Bar::thisIsNew() {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700347 ALOGI("SERVER(Bar) thisIsNew");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700348
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700349 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700350}
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
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700372template <typename T>
373static inline void EXPECT_OK(::android::hardware::Return<T> ret) {
374 EXPECT_TRUE(ret.getStatus().isOk());
Yifan Hong1dc87932016-08-19 09:51:01 -0700375}
376
377template<typename T, typename S>
378static inline bool EXPECT_ARRAYEQ(const T arr1, const S arr2, size_t size) {
379 for(size_t i = 0; i < size; i++)
380 if(arr1[i] != arr2[i])
381 return false;
382 return true;
383}
384
385
386template <class T>
387static void startServer(T server, const android::hardware::hidl_version kVersion,
388 const char *serviceName,
389 const char *tag) {
Andreas Huber8a82ff72016-08-04 10:29:39 -0700390 using namespace android::hardware;
Yifan Hong1dc87932016-08-19 09:51:01 -0700391 ALOGI("SERVER(%s) registering", tag);
Martijn Coenen4ff971c2016-09-08 13:40:02 +0200392 server->registerAsService(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;
Yifan Hong1dc87932016-08-19 09:51:01 -0700411 const hidl_version kVersion = make_hidl_version(1, 0);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700412
Martijn Coenen4ff971c2016-09-08 13:40:02 +0200413 foo = IFoo::getService("foo", kVersion);
Yifan Hong1dc87932016-08-19 09:51:01 -0700414 CHECK(foo != NULL);
415
Martijn Coenen4ff971c2016-09-08 13:40:02 +0200416 bar = IBar::getService("foo", kVersion);
Yifan Hong1dc87932016-08-19 09:51:01 -0700417 CHECK(bar != NULL);
418
Martijn Coenen4ff971c2016-09-08 13:40:02 +0200419 fooCb = IFooCallback::getService("foo callback", kVersion);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700420 CHECK(fooCb != NULL);
421
Yifan Hong1dc87932016-08-19 09:51:01 -0700422 ALOGI("Test setup complete");
423 }
424 virtual void TearDown() override {
425 }
426};
427
428class HidlEnvironment : public ::testing::Environment {
429private:
430 pid_t fooCallbackServerPid, barServerPid;
431public:
432 virtual void SetUp() {
433 ALOGI("Environment setup beginning...");
434 // use fork to create and kill to destroy server processes.
435 if ((barServerPid = fork()) == 0) {
436 // Fear me, I am a child.
437 startServer(new Bar, android::hardware::make_hidl_version(1, 0),
438 "foo", "Bar"); // never returns
439 return;
440 }
441
442 if ((fooCallbackServerPid = fork()) == 0) {
443 // Fear me, I am a second child.
444 startServer(new FooCallback, android::hardware::make_hidl_version(1, 0),
445 "foo callback", "FooCalback"); // never returns
446 return;
447 }
448
449 // Fear you not, I am parent.
450 sleep(1);
451 ALOGI("Environment setup complete.");
452 }
453
454 virtual void TearDown() {
455 // clean up by killing server processes.
456 ALOGI("Environment tear-down beginning...");
457 ALOGI("Killing servers...");
458 if(kill(barServerPid, SIGTERM)) {
459 ALOGE("Could not kill barServer; errno = %d", errno);
460 } else {
461 int status;
462 ALOGI("Waiting for barServer to exit...");
463 waitpid(barServerPid, &status, 0);
464 ALOGI("Continuing...");
465 }
466 if(kill(fooCallbackServerPid, SIGTERM)) {
467 ALOGE("Could not kill fooCallbackServer; errno = %d", errno);
468 } else {
469 int status;
470 ALOGI("Waiting for fooCallbackServer to exit...");
471 waitpid(barServerPid, &status, 0);
472 ALOGI("Continuing...");
473 }
474 ALOGI("Servers all killed.");
475 ALOGI("Environment tear-down complete.");
476 }
477};
478
479TEST_F(HidlTest, FooDoThisTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700480 ALOGI("CLIENT call doThis.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700481 EXPECT_OK(foo->doThis(1.0f));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700482 ALOGI("CLIENT doThis returned.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700483 EXPECT_EQ(true, true);
Yifan Hong1dc87932016-08-19 09:51:01 -0700484}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700485
Yifan Hong1dc87932016-08-19 09:51:01 -0700486TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700487 ALOGI("CLIENT call doThatAndReturnSomething.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700488 int32_t result = foo->doThatAndReturnSomething(2.0f);
489 ALOGI("CLIENT doThatAndReturnSomething returned %d.", result);
Yifan Hong1dc87932016-08-19 09:51:01 -0700490 EXPECT_EQ(result, 666);
491}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700492
Yifan Hong1dc87932016-08-19 09:51:01 -0700493TEST_F(HidlTest, FooDoQuiteABitTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700494 ALOGI("CLIENT call doQuiteABit");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700495 double something = foo->doQuiteABit(1, 2, 3.0f, 4.0);
496 ALOGI("CLIENT doQuiteABit returned %f.", something);
Yifan Hong1dc87932016-08-19 09:51:01 -0700497 EXPECT_DOUBLE_EQ(something, 666.5);
498}
499
500TEST_F(HidlTest, FooDoSomethingElseTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700501
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700502 ALOGI("CLIENT call doSomethingElse");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700503 int32_t param[15];
504 for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) {
505 param[i] = i;
506 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700507 EXPECT_OK(foo->doSomethingElse(param, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700508 ALOGI("CLIENT doSomethingElse returned %s.",
Steven Moreland88ca4512016-08-11 11:24:10 -0700509 arraylikeToString(something, 32).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700510 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
511 26, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2};
512 EXPECT_ARRAYEQ(something, expect, 32);
513 }));
514}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700515
Yifan Hong1dc87932016-08-19 09:51:01 -0700516TEST_F(HidlTest, FooDoStuffAndReturnAStringTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700517 ALOGI("CLIENT call doStuffAndReturnAString");
Yifan Hong1dc87932016-08-19 09:51:01 -0700518 EXPECT_OK(foo->doStuffAndReturnAString([&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700519 ALOGI("CLIENT doStuffAndReturnAString returned '%s'.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700520 something.c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700521 EXPECT_STREQ(something.c_str(), "Hello, world");
522 }));
523}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700524
Yifan Hong1dc87932016-08-19 09:51:01 -0700525TEST_F(HidlTest, FooMapThisVectorTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700526 hidl_vec<int32_t> vecParam;
527 vecParam.resize(10);
528 for (size_t i = 0; i < 10; ++i) {
529 vecParam[i] = i;
530 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700531 EXPECT_OK(foo->mapThisVector(vecParam, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700532 ALOGI("CLIENT mapThisVector returned %s.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700533 vecToString(something).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700534 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18};
535 EXPECT_ARRAYEQ(something, expect, something.size());
536 }));
537}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700538
Yifan Hong1dc87932016-08-19 09:51:01 -0700539TEST_F(HidlTest, FooCallMeTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700540 ALOGI("CLIENT call callMe.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700541 // callMe is oneway, should return instantly.
542 nsecs_t now;
543 now = systemTime();
544 EXPECT_OK(foo->callMe(fooCb));
545 EXPECT_TRUE(systemTime() - now < FooCallback::ONEWAY_TOLERANCE_NS);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700546 ALOGI("CLIENT callMe returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700547}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700548
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700549TEST_F(HidlTest, ForReportResultsTest) {
550
551 // Bar::callMe will invoke three methods on FooCallback; one will return
552 // right away (even though it is a two-way method); the second one will
553 // block Bar for FooCallback::DELAY_S seconds, and the third one will return
554 // to Bar right away (is oneway) but will itself block for DELAY_S seconds.
555 // We need a way to make sure that these three things have happened within
556 // 2*DELAY_S seconds plus some small tolerance.
557 //
558 // Method FooCallback::reportResults() takes a timeout parameter. It blocks for
559 // that length of time, while waiting for the three methods above to
560 // complete. It returns the information of whether each method was invoked,
561 // as well as how long the body of the method took to execute. We verify
562 // the information returned by reportResults() against the timeout we pass (which
563 // is long enough for the method bodies to execute, plus tolerance), and
564 // verify that eachof them executed, as expected, and took the length of
565 // time to execute that we also expect.
566
567 const nsecs_t reportResultsNs =
Andreas Huber03866f52016-08-30 14:19:52 -0700568 2 * FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS;
569
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700570 ALOGI("CLIENT: Waiting for up to %" PRId64 " seconds.",
571 nanoseconds_to_seconds(reportResultsNs));
572
573 fooCb->reportResults(reportResultsNs,
574 [&](int64_t timeLeftNs,
575 const IFooCallback::InvokeInfo invokeResults[3]) {
576 ALOGI("CLIENT: FooCallback::reportResults() is returning data.");
577 ALOGI("CLIENT: Waited for %" PRId64 " milliseconds.",
578 nanoseconds_to_milliseconds(reportResultsNs - timeLeftNs));
579
580 EXPECT_TRUE(0 <= timeLeftNs && timeLeftNs <= reportResultsNs);
581
582 // two-way method, was supposed to return right away
583 EXPECT_TRUE(invokeResults[0].invoked);
584 EXPECT_TRUE(invokeResults[0].timeNs <= invokeResults[0].callerBlockedNs);
585 EXPECT_TRUE(invokeResults[0].callerBlockedNs <= FooCallback::TOLERANCE_NS);
586 // two-way method, was supposed to block caller for DELAY_NS
587 EXPECT_TRUE(invokeResults[1].invoked);
588 EXPECT_TRUE(invokeResults[1].timeNs <= invokeResults[1].callerBlockedNs);
589 EXPECT_TRUE(invokeResults[1].callerBlockedNs <=
590 FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
591 // one-way method, do not block caller, but body was supposed to block for DELAY_NS
592 EXPECT_TRUE(invokeResults[2].invoked);
593 EXPECT_TRUE(invokeResults[2].callerBlockedNs <= FooCallback::ONEWAY_TOLERANCE_NS);
594 EXPECT_TRUE(invokeResults[2].timeNs <= FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
595 });
596}
597
598
599
Yifan Hong1dc87932016-08-19 09:51:01 -0700600TEST_F(HidlTest, FooUseAnEnumTest) {
601 ALOGI("CLIENT call useAnEnum.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700602 IFoo::SomeEnum sleepy = foo->useAnEnum(IFoo::SomeEnum::quux);
603 ALOGI("CLIENT useAnEnum returned %u", (unsigned)sleepy);
Yifan Hong1dc87932016-08-19 09:51:01 -0700604 EXPECT_EQ(sleepy, IFoo::SomeEnum::goober);
605}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700606
Yifan Hong1dc87932016-08-19 09:51:01 -0700607TEST_F(HidlTest, FooHaveAGooberTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700608 hidl_vec<IFoo::Goober> gooberVecParam;
609 gooberVecParam.resize(2);
610 gooberVecParam[0].name = "Hello";
611 gooberVecParam[1].name = "World";
612
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700613 ALOGI("CLIENT call haveAGooberVec.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700614 EXPECT_OK(foo->haveAGooberVec(gooberVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700615 ALOGI("CLIENT haveAGooberVec returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700616
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700617 ALOGI("CLIENT call haveaGoober.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700618 EXPECT_OK(foo->haveAGoober(gooberVecParam[0]));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700619 ALOGI("CLIENT haveaGoober returned.");
620
621 ALOGI("CLIENT call haveAGooberArray.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700622 IFoo::Goober gooberArrayParam[20];
Yifan Hong1dc87932016-08-19 09:51:01 -0700623 EXPECT_OK(foo->haveAGooberArray(gooberArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700624 ALOGI("CLIENT haveAGooberArray returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700625}
Steven Moreland88ca4512016-08-11 11:24:10 -0700626
Yifan Hong1dc87932016-08-19 09:51:01 -0700627TEST_F(HidlTest, FooHaveATypeFromAnotherFileTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700628 ALOGI("CLIENT call haveATypeFromAnotherFile.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700629 Abc abcParam{};
630 abcParam.x = "alphabet";
631 abcParam.y = 3.14f;
632 abcParam.z = new native_handle_t();
Yifan Hong1dc87932016-08-19 09:51:01 -0700633 EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700634 ALOGI("CLIENT haveATypeFromAnotherFile returned.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700635 delete abcParam.z;
636 abcParam.z = NULL;
Yifan Hong1dc87932016-08-19 09:51:01 -0700637}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700638
Yifan Hong1dc87932016-08-19 09:51:01 -0700639TEST_F(HidlTest, FooHaveSomeStringsTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700640 ALOGI("CLIENT call haveSomeStrings.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700641 hidl_string stringArrayParam[3];
642 stringArrayParam[0] = "What";
643 stringArrayParam[1] = "a";
644 stringArrayParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700645 EXPECT_OK(foo->haveSomeStrings(stringArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700646 ALOGI("CLIENT haveSomeStrings returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700647}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700648
Yifan Hong1dc87932016-08-19 09:51:01 -0700649TEST_F(HidlTest, FooHaveAStringVecTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700650 ALOGI("CLIENT call haveAStringVec.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700651 hidl_vec<hidl_string> stringVecParam;
652 stringVecParam.resize(3);
653 stringVecParam[0] = "What";
654 stringVecParam[1] = "a";
655 stringVecParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700656 EXPECT_OK(foo->haveAStringVec(stringVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700657 ALOGI("CLIENT haveAStringVec returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700658}
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700659
Yifan Hong1dc87932016-08-19 09:51:01 -0700660TEST_F(HidlTest, BarThisIsNewTest) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700661 // Now the tricky part, get access to the derived interface.
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700662 ALOGI("CLIENT call thisIsNew.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700663 EXPECT_OK(bar->thisIsNew());
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700664 ALOGI("CLIENT thisIsNew returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700665}
666
Yifan Hong1dc87932016-08-19 09:51:01 -0700667int main(int argc, char **argv) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700668
Yifan Hong1dc87932016-08-19 09:51:01 -0700669 ::testing::AddGlobalTestEnvironment(new HidlEnvironment);
670 ::testing::InitGoogleTest(&argc, argv);
671 int status = RUN_ALL_TESTS();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700672
Yifan Hong1dc87932016-08-19 09:51:01 -0700673 ALOGI("Test result = %d", status);
674 return status;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700675}