blob: 17170afafc685fc51f82c6e7fba0d6c551ca308e [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>
Martijn Coenena21f1492016-09-08 15:55:14 +0200387static void startServer(T server,
Yifan Hong1dc87932016-08-19 09:51:01 -0700388 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 Coenena21f1492016-09-08 15:55:14 +0200392 server->registerAsService(serviceName);
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;
Martijn Coenena21f1492016-09-08 15:55:14 +0200411 foo = IFoo::getService("foo");
Yifan Hong1dc87932016-08-19 09:51:01 -0700412 CHECK(foo != NULL);
413
Martijn Coenena21f1492016-09-08 15:55:14 +0200414 bar = IBar::getService("foo");
Yifan Hong1dc87932016-08-19 09:51:01 -0700415 CHECK(bar != NULL);
416
Martijn Coenena21f1492016-09-08 15:55:14 +0200417 fooCb = IFooCallback::getService("foo callback");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700418 CHECK(fooCb != NULL);
419
Yifan Hong1dc87932016-08-19 09:51:01 -0700420 ALOGI("Test setup complete");
421 }
422 virtual void TearDown() override {
423 }
424};
425
426class HidlEnvironment : public ::testing::Environment {
427private:
428 pid_t fooCallbackServerPid, barServerPid;
429public:
430 virtual void SetUp() {
431 ALOGI("Environment setup beginning...");
432 // use fork to create and kill to destroy server processes.
433 if ((barServerPid = fork()) == 0) {
434 // Fear me, I am a child.
Martijn Coenena21f1492016-09-08 15:55:14 +0200435 startServer(new Bar, "foo", "Bar"); // never returns
Yifan Hong1dc87932016-08-19 09:51:01 -0700436 return;
437 }
438
439 if ((fooCallbackServerPid = fork()) == 0) {
440 // Fear me, I am a second child.
Martijn Coenena21f1492016-09-08 15:55:14 +0200441 startServer(new FooCallback, "foo callback", "FooCalback"); // never returns
Yifan Hong1dc87932016-08-19 09:51:01 -0700442 return;
443 }
444
445 // Fear you not, I am parent.
446 sleep(1);
447 ALOGI("Environment setup complete.");
448 }
449
450 virtual void TearDown() {
451 // clean up by killing server processes.
452 ALOGI("Environment tear-down beginning...");
453 ALOGI("Killing servers...");
454 if(kill(barServerPid, SIGTERM)) {
455 ALOGE("Could not kill barServer; errno = %d", errno);
456 } else {
457 int status;
458 ALOGI("Waiting for barServer to exit...");
459 waitpid(barServerPid, &status, 0);
460 ALOGI("Continuing...");
461 }
462 if(kill(fooCallbackServerPid, SIGTERM)) {
463 ALOGE("Could not kill fooCallbackServer; errno = %d", errno);
464 } else {
465 int status;
466 ALOGI("Waiting for fooCallbackServer to exit...");
467 waitpid(barServerPid, &status, 0);
468 ALOGI("Continuing...");
469 }
470 ALOGI("Servers all killed.");
471 ALOGI("Environment tear-down complete.");
472 }
473};
474
475TEST_F(HidlTest, FooDoThisTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700476 ALOGI("CLIENT call doThis.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700477 EXPECT_OK(foo->doThis(1.0f));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700478 ALOGI("CLIENT doThis returned.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700479 EXPECT_EQ(true, true);
Yifan Hong1dc87932016-08-19 09:51:01 -0700480}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700481
Yifan Hong1dc87932016-08-19 09:51:01 -0700482TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700483 ALOGI("CLIENT call doThatAndReturnSomething.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700484 int32_t result = foo->doThatAndReturnSomething(2.0f);
485 ALOGI("CLIENT doThatAndReturnSomething returned %d.", result);
Yifan Hong1dc87932016-08-19 09:51:01 -0700486 EXPECT_EQ(result, 666);
487}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700488
Yifan Hong1dc87932016-08-19 09:51:01 -0700489TEST_F(HidlTest, FooDoQuiteABitTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700490 ALOGI("CLIENT call doQuiteABit");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700491 double something = foo->doQuiteABit(1, 2, 3.0f, 4.0);
492 ALOGI("CLIENT doQuiteABit returned %f.", something);
Yifan Hong1dc87932016-08-19 09:51:01 -0700493 EXPECT_DOUBLE_EQ(something, 666.5);
494}
495
496TEST_F(HidlTest, FooDoSomethingElseTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700497
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700498 ALOGI("CLIENT call doSomethingElse");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700499 int32_t param[15];
500 for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) {
501 param[i] = i;
502 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700503 EXPECT_OK(foo->doSomethingElse(param, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700504 ALOGI("CLIENT doSomethingElse returned %s.",
Steven Moreland88ca4512016-08-11 11:24:10 -0700505 arraylikeToString(something, 32).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700506 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
507 26, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2};
508 EXPECT_ARRAYEQ(something, expect, 32);
509 }));
510}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700511
Yifan Hong1dc87932016-08-19 09:51:01 -0700512TEST_F(HidlTest, FooDoStuffAndReturnAStringTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700513 ALOGI("CLIENT call doStuffAndReturnAString");
Yifan Hong1dc87932016-08-19 09:51:01 -0700514 EXPECT_OK(foo->doStuffAndReturnAString([&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700515 ALOGI("CLIENT doStuffAndReturnAString returned '%s'.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700516 something.c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700517 EXPECT_STREQ(something.c_str(), "Hello, world");
518 }));
519}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700520
Yifan Hong1dc87932016-08-19 09:51:01 -0700521TEST_F(HidlTest, FooMapThisVectorTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700522 hidl_vec<int32_t> vecParam;
523 vecParam.resize(10);
524 for (size_t i = 0; i < 10; ++i) {
525 vecParam[i] = i;
526 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700527 EXPECT_OK(foo->mapThisVector(vecParam, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700528 ALOGI("CLIENT mapThisVector returned %s.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700529 vecToString(something).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700530 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18};
531 EXPECT_ARRAYEQ(something, expect, something.size());
532 }));
533}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700534
Yifan Hong1dc87932016-08-19 09:51:01 -0700535TEST_F(HidlTest, FooCallMeTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700536 ALOGI("CLIENT call callMe.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700537 // callMe is oneway, should return instantly.
538 nsecs_t now;
539 now = systemTime();
540 EXPECT_OK(foo->callMe(fooCb));
541 EXPECT_TRUE(systemTime() - now < FooCallback::ONEWAY_TOLERANCE_NS);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700542 ALOGI("CLIENT callMe returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700543}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700544
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700545TEST_F(HidlTest, ForReportResultsTest) {
546
547 // Bar::callMe will invoke three methods on FooCallback; one will return
548 // right away (even though it is a two-way method); the second one will
549 // block Bar for FooCallback::DELAY_S seconds, and the third one will return
550 // to Bar right away (is oneway) but will itself block for DELAY_S seconds.
551 // We need a way to make sure that these three things have happened within
552 // 2*DELAY_S seconds plus some small tolerance.
553 //
554 // Method FooCallback::reportResults() takes a timeout parameter. It blocks for
555 // that length of time, while waiting for the three methods above to
556 // complete. It returns the information of whether each method was invoked,
557 // as well as how long the body of the method took to execute. We verify
558 // the information returned by reportResults() against the timeout we pass (which
559 // is long enough for the method bodies to execute, plus tolerance), and
560 // verify that eachof them executed, as expected, and took the length of
561 // time to execute that we also expect.
562
563 const nsecs_t reportResultsNs =
Andreas Huber03866f52016-08-30 14:19:52 -0700564 2 * FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS;
565
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700566 ALOGI("CLIENT: Waiting for up to %" PRId64 " seconds.",
567 nanoseconds_to_seconds(reportResultsNs));
568
569 fooCb->reportResults(reportResultsNs,
570 [&](int64_t timeLeftNs,
571 const IFooCallback::InvokeInfo invokeResults[3]) {
572 ALOGI("CLIENT: FooCallback::reportResults() is returning data.");
573 ALOGI("CLIENT: Waited for %" PRId64 " milliseconds.",
574 nanoseconds_to_milliseconds(reportResultsNs - timeLeftNs));
575
576 EXPECT_TRUE(0 <= timeLeftNs && timeLeftNs <= reportResultsNs);
577
578 // two-way method, was supposed to return right away
579 EXPECT_TRUE(invokeResults[0].invoked);
580 EXPECT_TRUE(invokeResults[0].timeNs <= invokeResults[0].callerBlockedNs);
581 EXPECT_TRUE(invokeResults[0].callerBlockedNs <= FooCallback::TOLERANCE_NS);
582 // two-way method, was supposed to block caller for DELAY_NS
583 EXPECT_TRUE(invokeResults[1].invoked);
584 EXPECT_TRUE(invokeResults[1].timeNs <= invokeResults[1].callerBlockedNs);
585 EXPECT_TRUE(invokeResults[1].callerBlockedNs <=
586 FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
587 // one-way method, do not block caller, but body was supposed to block for DELAY_NS
588 EXPECT_TRUE(invokeResults[2].invoked);
589 EXPECT_TRUE(invokeResults[2].callerBlockedNs <= FooCallback::ONEWAY_TOLERANCE_NS);
590 EXPECT_TRUE(invokeResults[2].timeNs <= FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
591 });
592}
593
594
595
Yifan Hong1dc87932016-08-19 09:51:01 -0700596TEST_F(HidlTest, FooUseAnEnumTest) {
597 ALOGI("CLIENT call useAnEnum.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700598 IFoo::SomeEnum sleepy = foo->useAnEnum(IFoo::SomeEnum::quux);
599 ALOGI("CLIENT useAnEnum returned %u", (unsigned)sleepy);
Yifan Hong1dc87932016-08-19 09:51:01 -0700600 EXPECT_EQ(sleepy, IFoo::SomeEnum::goober);
601}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700602
Yifan Hong1dc87932016-08-19 09:51:01 -0700603TEST_F(HidlTest, FooHaveAGooberTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700604 hidl_vec<IFoo::Goober> gooberVecParam;
605 gooberVecParam.resize(2);
606 gooberVecParam[0].name = "Hello";
607 gooberVecParam[1].name = "World";
608
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700609 ALOGI("CLIENT call haveAGooberVec.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700610 EXPECT_OK(foo->haveAGooberVec(gooberVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700611 ALOGI("CLIENT haveAGooberVec returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700612
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700613 ALOGI("CLIENT call haveaGoober.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700614 EXPECT_OK(foo->haveAGoober(gooberVecParam[0]));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700615 ALOGI("CLIENT haveaGoober returned.");
616
617 ALOGI("CLIENT call haveAGooberArray.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700618 IFoo::Goober gooberArrayParam[20];
Yifan Hong1dc87932016-08-19 09:51:01 -0700619 EXPECT_OK(foo->haveAGooberArray(gooberArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700620 ALOGI("CLIENT haveAGooberArray returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700621}
Steven Moreland88ca4512016-08-11 11:24:10 -0700622
Yifan Hong1dc87932016-08-19 09:51:01 -0700623TEST_F(HidlTest, FooHaveATypeFromAnotherFileTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700624 ALOGI("CLIENT call haveATypeFromAnotherFile.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700625 Abc abcParam{};
626 abcParam.x = "alphabet";
627 abcParam.y = 3.14f;
628 abcParam.z = new native_handle_t();
Yifan Hong1dc87932016-08-19 09:51:01 -0700629 EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700630 ALOGI("CLIENT haveATypeFromAnotherFile returned.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700631 delete abcParam.z;
632 abcParam.z = NULL;
Yifan Hong1dc87932016-08-19 09:51:01 -0700633}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700634
Yifan Hong1dc87932016-08-19 09:51:01 -0700635TEST_F(HidlTest, FooHaveSomeStringsTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700636 ALOGI("CLIENT call haveSomeStrings.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700637 hidl_string stringArrayParam[3];
638 stringArrayParam[0] = "What";
639 stringArrayParam[1] = "a";
640 stringArrayParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700641 EXPECT_OK(foo->haveSomeStrings(stringArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700642 ALOGI("CLIENT haveSomeStrings returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700643}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700644
Yifan Hong1dc87932016-08-19 09:51:01 -0700645TEST_F(HidlTest, FooHaveAStringVecTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700646 ALOGI("CLIENT call haveAStringVec.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700647 hidl_vec<hidl_string> stringVecParam;
648 stringVecParam.resize(3);
649 stringVecParam[0] = "What";
650 stringVecParam[1] = "a";
651 stringVecParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700652 EXPECT_OK(foo->haveAStringVec(stringVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700653 ALOGI("CLIENT haveAStringVec returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700654}
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700655
Yifan Hong1dc87932016-08-19 09:51:01 -0700656TEST_F(HidlTest, BarThisIsNewTest) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700657 // Now the tricky part, get access to the derived interface.
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700658 ALOGI("CLIENT call thisIsNew.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700659 EXPECT_OK(bar->thisIsNew());
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700660 ALOGI("CLIENT thisIsNew returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700661}
662
Yifan Hong1dc87932016-08-19 09:51:01 -0700663int main(int argc, char **argv) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700664
Yifan Hong1dc87932016-08-19 09:51:01 -0700665 ::testing::AddGlobalTestEnvironment(new HidlEnvironment);
666 ::testing::InitGoogleTest(&argc, argv);
667 int status = RUN_ALL_TESTS();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700668
Yifan Hong1dc87932016-08-19 09:51:01 -0700669 ALOGI("Test result = %d", status);
670 return status;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700671}