blob: c0b33d239059a9eb3008397cd3ca4f07cced3cb9 [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
Andreas Huberf9d49f12016-09-12 14:58:36 -0700165 Return<void> transposeMe(
166 const float *in /* float[3][5] */, transposeMe_cb _cb) override;
167
168 Return<void> callingDrWho(
169 const MultiDimensional &in,
170 callingDrWho_cb _hidl_cb) override;
171
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700172 Return<void> thisIsNew() override;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700173};
174
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700175Return<void> Bar::doThis(float param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700176 ALOGI("SERVER(Bar) doThis(%.2f)", param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700177
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700178 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700179}
180
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700181Return<int32_t> Bar::doThatAndReturnSomething(
Iliyan Malchevd856b052016-08-16 22:25:27 -0700182 int64_t param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700183 ALOGI("SERVER(Bar) doThatAndReturnSomething(%ld)", param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700184
Iliyan Malchevd856b052016-08-16 22:25:27 -0700185 return 666;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700186}
187
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700188Return<double> Bar::doQuiteABit(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700189 int32_t a,
190 int64_t b,
191 float c,
Iliyan Malchevd856b052016-08-16 22:25:27 -0700192 double d) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700193 ALOGI("SERVER(Bar) doQuiteABit(%d, %ld, %.2f, %.2f)", a, b, c, d);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700194
Iliyan Malchevd856b052016-08-16 22:25:27 -0700195 return 666.5;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700196}
197
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700198Return<void> Bar::doSomethingElse(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700199 const int32_t param[15], doSomethingElse_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700200 ALOGI("SERVER(Bar) doSomethingElse(...)");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700201
202 int32_t result[32] = { 0 };
203 for (size_t i = 0; i < 15; ++i) {
204 result[i] = 2 * param[i];
205 result[15 + i] = param[i];
206 }
207 result[30] = 1;
208 result[31] = 2;
209
210 _cb(result);
211
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700212 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700213}
214
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700215Return<void> Bar::doStuffAndReturnAString(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700216 doStuffAndReturnAString_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700217 ALOGI("SERVER(Bar) doStuffAndReturnAString");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700218
219 hidl_string s;
220 s = "Hello, world";
221
222 _cb(s);
223
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700224 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700225}
226
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700227Return<void> Bar::mapThisVector(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700228 const hidl_vec<int32_t> &param, mapThisVector_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700229 ALOGI("SERVER(Bar) mapThisVector");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700230
231 hidl_vec<int32_t> out;
Andreas Huber899b0632016-08-15 12:21:19 -0700232 out.resize(param.size());
Steven Moreland88ca4512016-08-11 11:24:10 -0700233
234 for (size_t i = 0; i < out.size(); ++i) {
235 out[i] = param[i] * 2;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700236 }
237
238 _cb(out);
239
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700240 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700241}
242
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700243Return<void> Bar::callMe(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700244 const sp<IFooCallback> &cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700245 ALOGI("SERVER(Bar) callMe %p", cb.get());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700246
247 if (cb != NULL) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700248
249 nsecs_t c[3];
250 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYou, " \
251 "should return immediately", cb.get());
252 c[0] = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700253 cb->heyItsYou(cb);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700254 c[0] = systemTime() - c[0];
255 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYou " \
256 "returned after %" PRId64 "ns", cb.get(), c[0]);
257
258 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYouIsntIt, " \
259 "should block for %" PRId64 " seconds", cb.get(),
260 FooCallback::DELAY_S);
261 c[1] = systemTime();
Iliyan Malchevd856b052016-08-16 22:25:27 -0700262 bool answer = cb->heyItsYouIsntIt(cb);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700263 c[1] = systemTime() - c[1];
264 ALOGI("SERVER(Bar) callMe %p IFooCallback::heyItsYouIsntIt " \
265 "responded with %d after %" PRId64 "ns", cb.get(), answer, c[1]);
266
267 ALOGI("SERVER(Bar) callMe %p calling " \
268 "IFooCallback::heyItsTheMeaningOfLife, " \
269 "should return immediately ", cb.get());
270 c[2] = systemTime();
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700271 cb->heyItsTheMeaningOfLife(42);
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700272 c[2] = systemTime() - c[2];
273 ALOGI("SERVER(Bar) callMe %p After call to " \
274 "IFooCallback::heyItsTheMeaningOfLife " \
275 "responded after %" PRId64 "ns", cb.get(), c[2]);
276
277 ALOGI("SERVER(Bar) callMe %p calling IFooCallback::youBlockedMeFor " \
278 "to report times", cb.get());
279 cb->youBlockedMeFor(c);
280 ALOGI("SERVER(Bar) callMe %p After call to " \
281 "IFooCallback::heyYouBlockedMeFor", cb.get());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700282 }
283
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700284 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700285}
286
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700287Return<Bar::SomeEnum> Bar::useAnEnum(SomeEnum param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700288 ALOGI("SERVER(Bar) useAnEnum %d", (int)param);
Andreas Huber9cd48d02016-08-03 14:25:59 -0700289
Iliyan Malchevd856b052016-08-16 22:25:27 -0700290 return SomeEnum::goober;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700291}
292
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700293Return<void> Bar::haveAGooberVec(const hidl_vec<Goober>& param) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700294 ALOGI("SERVER(Bar) haveAGooberVec &param = %p", &param);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700295
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700296 return Void();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700297}
298
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700299Return<void> Bar::haveAGoober(const Goober &g) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700300 ALOGI("SERVER(Bar) haveaGoober g=%p", &g);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700301
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700302 return Void();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700303}
304
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700305Return<void> Bar::haveAGooberArray(const Goober lots[20]) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700306 ALOGI("SERVER(Bar) haveAGooberArray lots = %p", lots);
Steven Moreland88ca4512016-08-11 11:24:10 -0700307
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700308 return Void();
Steven Moreland88ca4512016-08-11 11:24:10 -0700309}
310
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700311Return<void> Bar::haveATypeFromAnotherFile(const Abc &def) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700312 ALOGI("SERVER(Bar) haveATypeFromAnotherFile def=%p", &def);
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700313
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700314 return Void();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700315}
316
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700317Return<void> Bar::haveSomeStrings(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700318 const hidl_string array[3],
319 haveSomeStrings_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700320 ALOGI("SERVER(Bar) haveSomeStrings([\"%s\", \"%s\", \"%s\"])",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700321 array[0].c_str(),
322 array[1].c_str(),
323 array[2].c_str());
324
325 hidl_string result[2];
326 result[0] = "Hello";
327 result[1] = "World";
328
329 _cb(result);
330
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700331 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700332}
333
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700334Return<void> Bar::haveAStringVec(
Andreas Huber9cd48d02016-08-03 14:25:59 -0700335 const hidl_vec<hidl_string> &vector,
336 haveAStringVec_cb _cb) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700337 ALOGI("SERVER(Bar) haveAStringVec([\"%s\", \"%s\", \"%s\"])",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700338 vector[0].c_str(),
339 vector[1].c_str(),
340 vector[2].c_str());
341
342 hidl_vec<hidl_string> result;
343 result.resize(2);
344
345 result[0] = "Hello";
346 result[1] = "World";
347
348 _cb(result);
349
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700350 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700351}
352
Andreas Huberf9d49f12016-09-12 14:58:36 -0700353static std::string FloatArray2DToString(const float *x, size_t n1, size_t n2) {
354 std::string s;
355 s += "[";
356 for (size_t i = 0; i < n1; ++i) {
357 if (i > 0) {
358 s += ", ";
359 }
360
361 s += "[";
362 for (size_t j = 0; j < n2; ++j) {
363 if (j > 0) {
364 s += ", ";
365 }
366 s += std::to_string(x[i * n2 + j]);
367 }
368 s += "]";
369 }
370 s += "]";
371
372 return s;
373}
374
375Return<void> Bar::transposeMe(
376 const float *in /* float[3][5] */, transposeMe_cb _cb) {
377 ALOGI("SERVER(Bar) transposeMe(%s)",
378 FloatArray2DToString(in, 3, 5).c_str());
379
380 float out[5][3];
381 for (size_t i = 0; i < 5; ++i) {
382 for (size_t j = 0; j < 3; ++j) {
383 out[i][j] = in[5 * j + i];
384 }
385 }
386
387 _cb(&out[0][0]);
388
389 return Void();
390}
391
392static std::string QuuxToString(const IFoo::Quux &val) {
393 std::string s;
394
395 s = "Quux(first='";
396 s += val.first.c_str();
397 s += "', last='";
398 s += val.last.c_str();
399 s += "')";
400
401 return s;
402}
403
404static std::string MultiDimensionalToString(const IFoo::MultiDimensional &val) {
405 std::string s;
406
407 s += "MultiDimensional(";
408
409 s += "quuxMatrix=[";
410 for (size_t i = 0; i < 5; ++i) {
411 if (i > 0) {
412 s += ", ";
413 }
414
415 s += "[";
416 for (size_t j = 0; j < 3; ++j) {
417 if (j > 0) {
418 s += ", ";
419 }
420
421 s += QuuxToString(val.quuxMatrix[i][j]);
422 }
423 }
424 s += "]";
425
426 s += ")";
427
428 return s;
429}
430
431Return<void> Bar::callingDrWho(
432 const MultiDimensional &in, callingDrWho_cb _hidl_cb) {
433 ALOGI("SERVER(Bar) callingDrWho(%s)", MultiDimensionalToString(in).c_str());
434
435 MultiDimensional out;
436 for (size_t i = 0; i < 5; ++i) {
437 for (size_t j = 0; j < 3; ++j) {
438 out.quuxMatrix[i][j].first = in.quuxMatrix[4 - i][2 - j].last;
439 out.quuxMatrix[i][j].last = in.quuxMatrix[4 - i][2 - j].first;
440 }
441 }
442
443 _hidl_cb(out);
444
445 return Void();
446}
447
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700448Return<void> Bar::thisIsNew() {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700449 ALOGI("SERVER(Bar) thisIsNew");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700450
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700451 return Void();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700452}
453
Steven Moreland88ca4512016-08-11 11:24:10 -0700454template<typename I>
455static std::string arraylikeToString(const I data, size_t size) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700456 std::string out = "[";
457 for (size_t i = 0; i < size; ++i) {
458 if (i > 0) {
459 out += ", ";
460 }
461
462 out += ::android::String8::format("%d", data[i]).string();
463 }
464 out += "]";
465
466 return out;
467}
468
Yifan Hong1dc87932016-08-19 09:51:01 -0700469
Andreas Huber9cd48d02016-08-03 14:25:59 -0700470static std::string vecToString(const hidl_vec<int32_t> &vec) {
Steven Moreland88ca4512016-08-11 11:24:10 -0700471 return arraylikeToString(vec, vec.size());
Andreas Huber9cd48d02016-08-03 14:25:59 -0700472}
473
Steven Morelande70455b2016-09-14 15:46:36 -0700474#define EXPECT_OK(ret) EXPECT_TRUE(ret.getStatus().isOk())
Yifan Hong1dc87932016-08-19 09:51:01 -0700475
476template<typename T, typename S>
Steven Morelande70455b2016-09-14 15:46:36 -0700477static inline bool isArrayEqual(const T arr1, const S arr2, size_t size) {
Yifan Hong1dc87932016-08-19 09:51:01 -0700478 for(size_t i = 0; i < size; i++)
479 if(arr1[i] != arr2[i])
480 return false;
481 return true;
482}
483
484
485template <class T>
Martijn Coenena21f1492016-09-08 15:55:14 +0200486static void startServer(T server,
Yifan Hong1dc87932016-08-19 09:51:01 -0700487 const char *serviceName,
488 const char *tag) {
Andreas Huber8a82ff72016-08-04 10:29:39 -0700489 using namespace android::hardware;
Yifan Hong1dc87932016-08-19 09:51:01 -0700490 ALOGI("SERVER(%s) registering", tag);
Martijn Coenena21f1492016-09-08 15:55:14 +0200491 server->registerAsService(serviceName);
Yifan Hong1dc87932016-08-19 09:51:01 -0700492 ALOGI("SERVER(%s) starting", tag);
493 ProcessState::self()->setThreadPoolMaxThreadCount(0);
494 ProcessState::self()->startThreadPool();
495 IPCThreadState::self()->joinThreadPool(); // never ends. needs kill().
496 ALOGI("SERVER(%s) ends.", tag);
497}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700498
Andreas Huber9cd48d02016-08-03 14:25:59 -0700499
Yifan Hong1dc87932016-08-19 09:51:01 -0700500class HidlTest : public ::testing::Test {
501public:
502 sp<::android::hardware::IBinder> service;
503 sp<IFoo> foo;
504 sp<IBar> bar;
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700505 sp<IFooCallback> fooCb;
Yifan Hong1dc87932016-08-19 09:51:01 -0700506 sp<::android::hardware::IBinder> cbService;
507 virtual void SetUp() override {
508 ALOGI("Test setup beginning...");
509 using namespace android::hardware;
Martijn Coenena21f1492016-09-08 15:55:14 +0200510 foo = IFoo::getService("foo");
Yifan Hong1dc87932016-08-19 09:51:01 -0700511 CHECK(foo != NULL);
512
Martijn Coenena21f1492016-09-08 15:55:14 +0200513 bar = IBar::getService("foo");
Yifan Hong1dc87932016-08-19 09:51:01 -0700514 CHECK(bar != NULL);
515
Martijn Coenena21f1492016-09-08 15:55:14 +0200516 fooCb = IFooCallback::getService("foo callback");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700517 CHECK(fooCb != NULL);
518
Yifan Hong1dc87932016-08-19 09:51:01 -0700519 ALOGI("Test setup complete");
520 }
521 virtual void TearDown() override {
522 }
523};
524
525class HidlEnvironment : public ::testing::Environment {
526private:
527 pid_t fooCallbackServerPid, barServerPid;
528public:
529 virtual void SetUp() {
530 ALOGI("Environment setup beginning...");
531 // use fork to create and kill to destroy server processes.
532 if ((barServerPid = fork()) == 0) {
533 // Fear me, I am a child.
Martijn Coenena21f1492016-09-08 15:55:14 +0200534 startServer(new Bar, "foo", "Bar"); // never returns
Yifan Hong1dc87932016-08-19 09:51:01 -0700535 return;
536 }
537
538 if ((fooCallbackServerPid = fork()) == 0) {
539 // Fear me, I am a second child.
Martijn Coenena21f1492016-09-08 15:55:14 +0200540 startServer(new FooCallback, "foo callback", "FooCalback"); // never returns
Yifan Hong1dc87932016-08-19 09:51:01 -0700541 return;
542 }
543
544 // Fear you not, I am parent.
545 sleep(1);
546 ALOGI("Environment setup complete.");
547 }
548
549 virtual void TearDown() {
550 // clean up by killing server processes.
551 ALOGI("Environment tear-down beginning...");
552 ALOGI("Killing servers...");
553 if(kill(barServerPid, SIGTERM)) {
554 ALOGE("Could not kill barServer; errno = %d", errno);
555 } else {
556 int status;
557 ALOGI("Waiting for barServer to exit...");
558 waitpid(barServerPid, &status, 0);
559 ALOGI("Continuing...");
560 }
561 if(kill(fooCallbackServerPid, SIGTERM)) {
562 ALOGE("Could not kill fooCallbackServer; errno = %d", errno);
563 } else {
564 int status;
565 ALOGI("Waiting for fooCallbackServer to exit...");
566 waitpid(barServerPid, &status, 0);
567 ALOGI("Continuing...");
568 }
569 ALOGI("Servers all killed.");
570 ALOGI("Environment tear-down complete.");
571 }
572};
573
574TEST_F(HidlTest, FooDoThisTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700575 ALOGI("CLIENT call doThis.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700576 EXPECT_OK(foo->doThis(1.0f));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700577 ALOGI("CLIENT doThis returned.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700578 EXPECT_EQ(true, true);
Yifan Hong1dc87932016-08-19 09:51:01 -0700579}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700580
Yifan Hong1dc87932016-08-19 09:51:01 -0700581TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700582 ALOGI("CLIENT call doThatAndReturnSomething.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700583 int32_t result = foo->doThatAndReturnSomething(2.0f);
584 ALOGI("CLIENT doThatAndReturnSomething returned %d.", result);
Yifan Hong1dc87932016-08-19 09:51:01 -0700585 EXPECT_EQ(result, 666);
586}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700587
Yifan Hong1dc87932016-08-19 09:51:01 -0700588TEST_F(HidlTest, FooDoQuiteABitTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700589 ALOGI("CLIENT call doQuiteABit");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700590 double something = foo->doQuiteABit(1, 2, 3.0f, 4.0);
591 ALOGI("CLIENT doQuiteABit returned %f.", something);
Yifan Hong1dc87932016-08-19 09:51:01 -0700592 EXPECT_DOUBLE_EQ(something, 666.5);
593}
594
595TEST_F(HidlTest, FooDoSomethingElseTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700596
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700597 ALOGI("CLIENT call doSomethingElse");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700598 int32_t param[15];
599 for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) {
600 param[i] = i;
601 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700602 EXPECT_OK(foo->doSomethingElse(param, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700603 ALOGI("CLIENT doSomethingElse returned %s.",
Steven Moreland88ca4512016-08-11 11:24:10 -0700604 arraylikeToString(something, 32).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700605 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
606 26, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2};
Steven Morelande70455b2016-09-14 15:46:36 -0700607 EXPECT_TRUE(isArrayEqual(something, expect, 32));
Yifan Hong1dc87932016-08-19 09:51:01 -0700608 }));
609}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700610
Yifan Hong1dc87932016-08-19 09:51:01 -0700611TEST_F(HidlTest, FooDoStuffAndReturnAStringTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700612 ALOGI("CLIENT call doStuffAndReturnAString");
Yifan Hong1dc87932016-08-19 09:51:01 -0700613 EXPECT_OK(foo->doStuffAndReturnAString([&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700614 ALOGI("CLIENT doStuffAndReturnAString returned '%s'.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700615 something.c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700616 EXPECT_STREQ(something.c_str(), "Hello, world");
617 }));
618}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700619
Yifan Hong1dc87932016-08-19 09:51:01 -0700620TEST_F(HidlTest, FooMapThisVectorTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700621 hidl_vec<int32_t> vecParam;
622 vecParam.resize(10);
623 for (size_t i = 0; i < 10; ++i) {
624 vecParam[i] = i;
625 }
Yifan Hong1dc87932016-08-19 09:51:01 -0700626 EXPECT_OK(foo->mapThisVector(vecParam, [&](const auto &something) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700627 ALOGI("CLIENT mapThisVector returned %s.",
Andreas Huber9cd48d02016-08-03 14:25:59 -0700628 vecToString(something).c_str());
Yifan Hong1dc87932016-08-19 09:51:01 -0700629 int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18};
Steven Morelande70455b2016-09-14 15:46:36 -0700630 EXPECT_TRUE(isArrayEqual(something, expect, something.size()));
Yifan Hong1dc87932016-08-19 09:51:01 -0700631 }));
632}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700633
Yifan Hong1dc87932016-08-19 09:51:01 -0700634TEST_F(HidlTest, FooCallMeTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700635 ALOGI("CLIENT call callMe.");
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700636 // callMe is oneway, should return instantly.
637 nsecs_t now;
638 now = systemTime();
639 EXPECT_OK(foo->callMe(fooCb));
640 EXPECT_TRUE(systemTime() - now < FooCallback::ONEWAY_TOLERANCE_NS);
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700641 ALOGI("CLIENT callMe returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700642}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700643
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700644TEST_F(HidlTest, ForReportResultsTest) {
645
646 // Bar::callMe will invoke three methods on FooCallback; one will return
647 // right away (even though it is a two-way method); the second one will
648 // block Bar for FooCallback::DELAY_S seconds, and the third one will return
649 // to Bar right away (is oneway) but will itself block for DELAY_S seconds.
650 // We need a way to make sure that these three things have happened within
651 // 2*DELAY_S seconds plus some small tolerance.
652 //
653 // Method FooCallback::reportResults() takes a timeout parameter. It blocks for
654 // that length of time, while waiting for the three methods above to
655 // complete. It returns the information of whether each method was invoked,
656 // as well as how long the body of the method took to execute. We verify
657 // the information returned by reportResults() against the timeout we pass (which
658 // is long enough for the method bodies to execute, plus tolerance), and
659 // verify that eachof them executed, as expected, and took the length of
660 // time to execute that we also expect.
661
662 const nsecs_t reportResultsNs =
Andreas Huber03866f52016-08-30 14:19:52 -0700663 2 * FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS;
664
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700665 ALOGI("CLIENT: Waiting for up to %" PRId64 " seconds.",
666 nanoseconds_to_seconds(reportResultsNs));
667
668 fooCb->reportResults(reportResultsNs,
669 [&](int64_t timeLeftNs,
670 const IFooCallback::InvokeInfo invokeResults[3]) {
671 ALOGI("CLIENT: FooCallback::reportResults() is returning data.");
672 ALOGI("CLIENT: Waited for %" PRId64 " milliseconds.",
673 nanoseconds_to_milliseconds(reportResultsNs - timeLeftNs));
674
675 EXPECT_TRUE(0 <= timeLeftNs && timeLeftNs <= reportResultsNs);
676
677 // two-way method, was supposed to return right away
678 EXPECT_TRUE(invokeResults[0].invoked);
679 EXPECT_TRUE(invokeResults[0].timeNs <= invokeResults[0].callerBlockedNs);
680 EXPECT_TRUE(invokeResults[0].callerBlockedNs <= FooCallback::TOLERANCE_NS);
681 // two-way method, was supposed to block caller for DELAY_NS
682 EXPECT_TRUE(invokeResults[1].invoked);
683 EXPECT_TRUE(invokeResults[1].timeNs <= invokeResults[1].callerBlockedNs);
684 EXPECT_TRUE(invokeResults[1].callerBlockedNs <=
685 FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
686 // one-way method, do not block caller, but body was supposed to block for DELAY_NS
687 EXPECT_TRUE(invokeResults[2].invoked);
688 EXPECT_TRUE(invokeResults[2].callerBlockedNs <= FooCallback::ONEWAY_TOLERANCE_NS);
689 EXPECT_TRUE(invokeResults[2].timeNs <= FooCallback::DELAY_NS + FooCallback::TOLERANCE_NS);
690 });
691}
692
693
694
Yifan Hong1dc87932016-08-19 09:51:01 -0700695TEST_F(HidlTest, FooUseAnEnumTest) {
696 ALOGI("CLIENT call useAnEnum.");
Iliyan Malchevd856b052016-08-16 22:25:27 -0700697 IFoo::SomeEnum sleepy = foo->useAnEnum(IFoo::SomeEnum::quux);
698 ALOGI("CLIENT useAnEnum returned %u", (unsigned)sleepy);
Yifan Hong1dc87932016-08-19 09:51:01 -0700699 EXPECT_EQ(sleepy, IFoo::SomeEnum::goober);
700}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700701
Yifan Hong1dc87932016-08-19 09:51:01 -0700702TEST_F(HidlTest, FooHaveAGooberTest) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700703 hidl_vec<IFoo::Goober> gooberVecParam;
704 gooberVecParam.resize(2);
705 gooberVecParam[0].name = "Hello";
706 gooberVecParam[1].name = "World";
707
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700708 ALOGI("CLIENT call haveAGooberVec.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700709 EXPECT_OK(foo->haveAGooberVec(gooberVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700710 ALOGI("CLIENT haveAGooberVec returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700711
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700712 ALOGI("CLIENT call haveaGoober.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700713 EXPECT_OK(foo->haveAGoober(gooberVecParam[0]));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700714 ALOGI("CLIENT haveaGoober returned.");
715
716 ALOGI("CLIENT call haveAGooberArray.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700717 IFoo::Goober gooberArrayParam[20];
Yifan Hong1dc87932016-08-19 09:51:01 -0700718 EXPECT_OK(foo->haveAGooberArray(gooberArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700719 ALOGI("CLIENT haveAGooberArray returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700720}
Steven Moreland88ca4512016-08-11 11:24:10 -0700721
Yifan Hong1dc87932016-08-19 09:51:01 -0700722TEST_F(HidlTest, FooHaveATypeFromAnotherFileTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700723 ALOGI("CLIENT call haveATypeFromAnotherFile.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700724 Abc abcParam{};
725 abcParam.x = "alphabet";
726 abcParam.y = 3.14f;
727 abcParam.z = new native_handle_t();
Yifan Hong1dc87932016-08-19 09:51:01 -0700728 EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700729 ALOGI("CLIENT haveATypeFromAnotherFile returned.");
Steven Moreland88ca4512016-08-11 11:24:10 -0700730 delete abcParam.z;
731 abcParam.z = NULL;
Yifan Hong1dc87932016-08-19 09:51:01 -0700732}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700733
Yifan Hong1dc87932016-08-19 09:51:01 -0700734TEST_F(HidlTest, FooHaveSomeStringsTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700735 ALOGI("CLIENT call haveSomeStrings.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700736 hidl_string stringArrayParam[3];
737 stringArrayParam[0] = "What";
738 stringArrayParam[1] = "a";
739 stringArrayParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700740 EXPECT_OK(foo->haveSomeStrings(stringArrayParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700741 ALOGI("CLIENT haveSomeStrings returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700742}
Andreas Huber9cd48d02016-08-03 14:25:59 -0700743
Yifan Hong1dc87932016-08-19 09:51:01 -0700744TEST_F(HidlTest, FooHaveAStringVecTest) {
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700745 ALOGI("CLIENT call haveAStringVec.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700746 hidl_vec<hidl_string> stringVecParam;
747 stringVecParam.resize(3);
748 stringVecParam[0] = "What";
749 stringVecParam[1] = "a";
750 stringVecParam[2] = "disaster";
Yifan Hong1dc87932016-08-19 09:51:01 -0700751 EXPECT_OK(foo->haveAStringVec(stringVecParam));
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700752 ALOGI("CLIENT haveAStringVec returned.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700753}
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700754
Andreas Huberf9d49f12016-09-12 14:58:36 -0700755TEST_F(HidlTest, FooTransposeMeTest) {
756 float in[3][5];
757 float k = 1.0f;
758 for (size_t i = 0; i < 3; ++i) {
759 for (size_t j = 0; j < 5; ++j, ++k) {
760 in[i][j] = k;
761 }
762 }
763
764 ALOGI("CLIENT call transposeMe(%s).",
765 FloatArray2DToString(&in[0][0], 3, 5).c_str());
766
767 EXPECT_OK(foo->transposeMe(
768 &in[0][0],
769 [&](const auto &out) {
770 ALOGI("CLIENT transposeMe returned %s.",
771 FloatArray2DToString(out, 5, 3).c_str());
772
773 for (size_t i = 0; i < 3; ++i) {
774 for (size_t j = 0; j < 5; ++j) {
775 EXPECT_EQ(out[3 * j + i], in[i][j]);
776 }
777 }
778 }));
779}
780
781TEST_F(HidlTest, FooCallingDrWhoTest) {
782 IFoo::MultiDimensional in;
783
784 size_t k = 0;
785 for (size_t i = 0; i < 5; ++i) {
786 for (size_t j = 0; j < 3; ++j, ++k) {
787 in.quuxMatrix[i][j].first = ("First " + std::to_string(k)).c_str();
788 in.quuxMatrix[i][j].last = ("Last " + std::to_string(15-k)).c_str();
789 }
790 }
791
792 ALOGI("CLIENT call callingDrWho(%s).",
793 MultiDimensionalToString(in).c_str());
794
795 EXPECT_OK(foo->callingDrWho(
796 in,
797 [&](const auto &out) {
798 ALOGI("CLIENT callingDrWho returned %s.",
799 MultiDimensionalToString(out).c_str());
800
801 for (size_t i = 0; i < 5; ++i) {
802 for (size_t j = 0; j < 3; ++j) {
803 EXPECT_STREQ(
804 out.quuxMatrix[i][j].first.c_str(),
805 in.quuxMatrix[4-i][2-j].last.c_str());
806
807 EXPECT_STREQ(
808 out.quuxMatrix[i][j].last.c_str(),
809 in.quuxMatrix[4-i][2-j].first.c_str());
810 }
811 }
812 }));
813}
814
Yifan Hong1dc87932016-08-19 09:51:01 -0700815TEST_F(HidlTest, BarThisIsNewTest) {
Iliyan Malchev0acf4192016-08-22 19:33:20 -0700816 // Now the tricky part, get access to the derived interface.
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700817 ALOGI("CLIENT call thisIsNew.");
Yifan Hong1dc87932016-08-19 09:51:01 -0700818 EXPECT_OK(bar->thisIsNew());
Iliyan Malchevb31e10c2016-08-13 23:03:25 -0700819 ALOGI("CLIENT thisIsNew returned.");
Andreas Huber9cd48d02016-08-03 14:25:59 -0700820}
821
Yifan Hong1dc87932016-08-19 09:51:01 -0700822int main(int argc, char **argv) {
Andreas Huber9cd48d02016-08-03 14:25:59 -0700823
Yifan Hong1dc87932016-08-19 09:51:01 -0700824 ::testing::AddGlobalTestEnvironment(new HidlEnvironment);
825 ::testing::InitGoogleTest(&argc, argv);
826 int status = RUN_ALL_TESTS();
Andreas Huber9cd48d02016-08-03 14:25:59 -0700827
Yifan Hong1dc87932016-08-19 09:51:01 -0700828 ALOGI("Test result = %d", status);
829 return status;
Andreas Huber9cd48d02016-08-03 14:25:59 -0700830}