1
2#define LOG_TAG "hidl_test"
3
4#include "Foo.h"
5#include <android-base/logging.h>
6#include <hidl-test/FooHelper.h>
7#include <inttypes.h>
8#include <utils/Timers.h>
9
10namespace android {
11namespace hardware {
12namespace tests {
13namespace foo {
14namespace V1_0 {
15namespace implementation {
16
17// Methods from ::android::hardware::tests::foo::V1_0::IFoo follow.
18Return<void> Foo::convertToBoolIfSmall(Discriminator d, const hidl_vec<Union>& u,
19                                       convertToBoolIfSmall_cb _hidl_cb) {
20    hidl_vec<ContainsUnion> res(u.size());
21    for (size_t i = 0; i < u.size(); i++) {
22        ContainsUnion& outValue = res[i];
23
24        if (d == Discriminator::BOOL) {
25            outValue.discriminator = Discriminator::BOOL;
26            outValue.value.boolValue = u[i].boolValue;
27        } else {
28            uint64_t value = u[i].intValue;
29            if (value == 0 || value == 1) {
30                outValue.discriminator = Discriminator::BOOL;
31                outValue.value.boolValue = static_cast<bool>(value);
32            } else {
33                outValue.discriminator = Discriminator::INT;
34                outValue.value.intValue = value;
35            }
36        }
37    }
38    _hidl_cb(res);
39    return Void();
40}
41
42Return<void> Foo::doThis(float param) {
43    LOG(INFO) << "SERVER(Foo) doThis(" << param << ")";
44
45    return Void();
46}
47
48Return<int32_t> Foo::doThatAndReturnSomething(
49        int64_t param) {
50    LOG(INFO) << "SERVER(Foo) doThatAndReturnSomething(" << param << ")";
51
52    return 666;
53}
54
55Return<double> Foo::doQuiteABit(
56        int32_t a,
57        int64_t b,
58        float c,
59        double d) {
60    LOG(INFO) << "SERVER(Foo) doQuiteABit("
61              << a
62              << ", "
63              << b
64              << ", "
65              << c
66              << ", "
67              << d
68              << ")";
69
70    return 666.5;
71}
72
73Return<void> Foo::doSomethingElse(
74        const hidl_array<int32_t, 15> &param, doSomethingElse_cb _cb) {
75    LOG(INFO) << "SERVER(Foo) doSomethingElse(...)";
76
77    hidl_array<int32_t, 32> result;
78    for (size_t i = 0; i < 15; ++i) {
79        result[i] = 2 * param[i];
80        result[15 + i] = param[i];
81    }
82    result[30] = 1;
83    result[31] = 2;
84
85    _cb(result);
86
87    return Void();
88}
89
90Return<void> Foo::doStuffAndReturnAString(
91        doStuffAndReturnAString_cb _cb) {
92    LOG(INFO) << "SERVER(Foo) doStuffAndReturnAString";
93
94    _cb("Hello, world");
95
96    return Void();
97}
98
99Return<void> Foo::mapThisVector(
100        const hidl_vec<int32_t> &param, mapThisVector_cb _cb) {
101    LOG(INFO) << "SERVER(Foo) mapThisVector";
102
103    hidl_vec<int32_t> out;
104    out.resize(param.size());
105
106    for (size_t i = 0; i < out.size(); ++i) {
107        out[i] = param[i] * 2;
108    }
109
110    _cb(out);
111
112    return Void();
113}
114
115Return<void> Foo::callMe(
116        const sp<IFooCallback> &cb) {
117    LOG(INFO) << "SERVER(Foo) callMe " << cb.get();
118
119    if (cb != NULL) {
120        hidl_array<nsecs_t, 3> c;
121        LOG(INFO) << "SERVER(Foo) callMe "
122                  << cb.get()
123                  << " calling IFooCallback::heyItsYou, should return immediately";
124        c[0] = systemTime();
125        cb->heyItsYou(cb);
126        c[0] = systemTime() - c[0];
127        LOG(INFO) << "SERVER(Foo) callMe "
128                  << cb.get()
129                  << " calling IFooCallback::heyItsYou, returned after"
130                  << c[0]
131                  << "ns";
132        LOG(INFO) << "SERVER(Foo) callMe "
133                  << cb.get()
134                  << " calling IFooCallback::heyItsYouIsntIt, should block for"
135                  << DELAY_S
136                  << " seconds";
137        c[1] = systemTime();
138        bool answer = cb->heyItsYouIsntIt(cb);
139        c[1] = systemTime() - c[1];
140
141        LOG(INFO) << "SERVER(Foo) callMe "
142                  << cb.get()
143                  << " calling IFooCallback::heyItsYouIsntIt, responded with "
144                  << answer
145                  << " after "
146                  << c[1]
147                  << "ns";
148
149        LOG(INFO) << "SERVER(Foo) callMe "
150                  << cb.get()
151                  << " calling IFooCallback::heyItsTheMeaningOfLife,"
152                  << " should return immediately";
153        c[2] = systemTime();
154        cb->heyItsTheMeaningOfLife(42);
155        c[2] = systemTime() - c[2];
156
157        LOG(INFO) << "SERVER(Foo) callMe "
158                  << cb.get()
159                  << " cAfter call to IFooCallback::heyItsTheMeaningOfLife responded after "
160                  << c[2]
161                  << "ns";
162        LOG(INFO) << "SERVER(Foo) callMe "
163                  << cb.get()
164                  << " calling IFooCallback::youBlockedMeFor to report times";
165        cb->youBlockedMeFor(c);
166        LOG(INFO) << "SERVER(Foo) callMe "
167                  << cb.get()
168                  << " After call to IFooCallback::youBlockedMeFor";
169    }
170
171    return Void();
172}
173
174Return<Foo::SomeEnum> Foo::useAnEnum(SomeEnum param) {
175    LOG(INFO) << "SERVER(Foo) useAnEnum " << (int)param;
176
177    return SomeEnum::goober;
178}
179
180Return<void> Foo::haveAGooberVec(const hidl_vec<Goober>& param) {
181    LOG(INFO) << "SERVER(Foo) haveAGooberVec &param = " << &param;
182
183    return Void();
184}
185
186Return<void> Foo::haveAGoober(const Goober &g) {
187    LOG(INFO) << "SERVER(Foo) haveaGoober g=" << &g;
188
189    return Void();
190}
191
192Return<void> Foo::haveAGooberArray(const hidl_array<Goober, 20> & /* lots */) {
193    LOG(INFO) << "SERVER(Foo) haveAGooberArray";
194
195    return Void();
196}
197
198Return<void> Foo::haveATypeFromAnotherFile(const Abc &def) {
199    LOG(INFO) << "SERVER(Foo) haveATypeFromAnotherFile def=" << &def;
200
201    return Void();
202}
203
204Return<void> Foo::haveSomeStrings(
205        const hidl_array<hidl_string, 3> &array,
206        haveSomeStrings_cb _cb) {
207
208    LOG(INFO) << "SERVER(Foo) haveSomeStrings([\""
209              << array[0].c_str()
210              << "\", \""
211              << array[1].c_str()
212              << "\", \""
213              << array[2].c_str()
214              << "\"])";
215
216    hidl_array<hidl_string, 2> result;
217    result[0] = "Hello";
218    result[1] = "World";
219
220    _cb(result);
221
222    return Void();
223}
224
225Return<void> Foo::haveAStringVec(
226        const hidl_vec<hidl_string> &vector,
227        haveAStringVec_cb _cb) {
228    LOG(INFO) << "SERVER(Foo) haveAStringVec([\""
229              << vector[0].c_str()
230              << "\", \""
231              << vector[1].c_str()
232              << "\", \""
233              << vector[2].c_str()
234              << "\"])";
235
236    hidl_vec<hidl_string> result;
237    result.resize(2);
238
239    result[0] = "Hello";
240    result[1] = "World";
241
242    _cb(result);
243
244    return Void();
245}
246
247Return<void> Foo::transposeMe(
248        const hidl_array<float, 3, 5> &in, transposeMe_cb _cb) {
249    LOG(INFO) << "SERVER(Foo) transposeMe(" << to_string(in).c_str() << ")";
250
251    hidl_array<float, 5, 3> out;
252    for (size_t i = 0; i < 5; ++i) {
253        for (size_t j = 0; j < 3; ++j) {
254            out[i][j] = in[j][i];
255        }
256    }
257
258    LOG(INFO) << "SERVER(Foo) transposeMe returning " << to_string(out).c_str();
259
260    _cb(out);
261
262    return Void();
263}
264
265Return<void> Foo::callingDrWho(
266        const MultiDimensional &in, callingDrWho_cb _hidl_cb) {
267    LOG(INFO) << "SERVER(Foo) callingDrWho(" << MultiDimensionalToString(in).c_str() << ")";
268
269    MultiDimensional out;
270    for (size_t i = 0; i < 5; ++i) {
271        for (size_t j = 0; j < 3; ++j) {
272            out.quuxMatrix[i][j].first = in.quuxMatrix[4 - i][2 - j].last;
273            out.quuxMatrix[i][j].last = in.quuxMatrix[4 - i][2 - j].first;
274        }
275    }
276
277    _hidl_cb(out);
278
279    return Void();
280}
281
282Return<void> Foo::transpose(const StringMatrix5x3 &in, transpose_cb _hidl_cb) {
283    LOG(INFO) << "SERVER(Foo) transpose " << to_string(in);
284
285    StringMatrix3x5 out;
286    for (size_t i = 0; i < 3; ++i) {
287        for (size_t j = 0; j < 5; ++j) {
288            out.s[i][j] = in.s[j][i];
289        }
290    }
291
292    _hidl_cb(out);
293
294    return Void();
295}
296
297Return<void> Foo::transpose2(
298        const hidl_array<hidl_string, 5, 3> &in, transpose2_cb _hidl_cb) {
299    LOG(INFO) << "SERVER(Foo) transpose2 " << to_string(in);
300
301    hidl_array<hidl_string, 3, 5> out;
302    for (size_t i = 0; i < 3; ++i) {
303        for (size_t j = 0; j < 5; ++j) {
304            out[i][j] = in[j][i];
305        }
306    }
307
308    _hidl_cb(out);
309
310    return Void();
311}
312
313Return<void> Foo::sendVec(
314        const hidl_vec<uint8_t> &data, sendVec_cb _hidl_cb) {
315    _hidl_cb(data);
316
317    return Void();
318}
319
320Return<void> Foo::sendVecVec(sendVecVec_cb _hidl_cb) {
321    hidl_vec<hidl_vec<uint8_t>> data;
322    _hidl_cb(data);
323
324    return Void();
325}
326
327Return<void> Foo::haveAVectorOfInterfaces(
328        const hidl_vec<sp<ISimple> > &in,
329        haveAVectorOfInterfaces_cb _hidl_cb) {
330    _hidl_cb(in);
331
332    return Void();
333}
334
335Return<void> Foo::haveAVectorOfGenericInterfaces(
336        const hidl_vec<sp<android::hidl::base::V1_0::IBase> > &in,
337        haveAVectorOfGenericInterfaces_cb _hidl_cb) {
338    _hidl_cb(in);
339    return Void();
340}
341
342Return<void> Foo::createMyHandle(createMyHandle_cb _hidl_cb) {
343    native_handle_t* nh = native_handle_create(0, 10);
344    int data[] = {2,3,5,7,11,13,17,19,21,23};
345    CHECK(sizeof(data) == 10 * sizeof(int));
346    memcpy(nh->data, data, sizeof(data));
347    mHandles.push_back(nh);
348
349    MyHandle h;
350    h.guard = 666;
351    h.h = nh;
352    _hidl_cb(h);
353    return Void();
354}
355
356Return<void> Foo::createHandles(uint32_t size, createHandles_cb _hidl_cb) {
357    hidl_vec<hidl_handle> handles;
358    handles.resize(size);
359    for(uint32_t i = 0; i < size; ++i) {
360        createMyHandle([&](const MyHandle& h) {
361            handles[i] = h.h;
362        });
363    }
364    _hidl_cb(handles);
365    return Void();
366}
367
368Return<void> Foo::closeHandles() {
369    for(native_handle_t* h : mHandles) {
370        native_handle_delete(h);
371    }
372    mHandles.clear();
373    return Void();
374}
375
376Return<void> Foo::echoNullInterface(const sp<IFooCallback> &cb, echoNullInterface_cb _hidl_cb) {
377    _hidl_cb(cb == nullptr, cb);
378
379    return Void();
380}
381
382IFoo* HIDL_FETCH_IFoo(const char* /* name */) {
383    return new Foo();
384}
385
386} // namespace implementation
387}  // namespace V1_0
388}  // namespace foo
389}  // namespace tests
390}  // namespace hardware
391}  // namespace android
392