OSDN Git Service

libbinder: Add int64_t/uint64_t to SafeInterface
[android-x86/frameworks-native.git] / libs / binder / tests / binderSafeInterfaceTest.cpp
1 /*
2  * Copyright 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <binder/SafeInterface.h>
18
19 #include <binder/IInterface.h>
20 #include <binder/IPCThreadState.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/Parcel.h>
23 #include <binder/Parcelable.h>
24 #include <binder/ProcessState.h>
25
26 #pragma clang diagnostic push
27 #pragma clang diagnostic ignored "-Weverything"
28 #include <gtest/gtest.h>
29 #pragma clang diagnostic pop
30
31 #include <optional>
32
33 using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
34
35 namespace android {
36 namespace tests {
37
38 // This class serves two purposes:
39 //   1) It ensures that the implementation doesn't require copying or moving the data (for
40 //      efficiency purposes)
41 //   2) It tests that Parcelables can be passed correctly
42 class NoCopyNoMove : public Parcelable {
43 public:
44     NoCopyNoMove() = default;
45     explicit NoCopyNoMove(int32_t value) : mValue(value) {}
46     ~NoCopyNoMove() override = default;
47
48     // Not copyable
49     NoCopyNoMove(const NoCopyNoMove&) = delete;
50     NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
51
52     // Not movable
53     NoCopyNoMove(NoCopyNoMove&&) = delete;
54     NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
55
56     // Parcelable interface
57     status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
58     status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
59
60     int32_t getValue() const { return mValue; }
61     void setValue(int32_t value) { mValue = value; }
62
63 private:
64     int32_t mValue = 0;
65     uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
66 };
67
68 struct TestFlattenable : Flattenable<TestFlattenable> {
69     TestFlattenable() = default;
70     explicit TestFlattenable(int32_t v) : value(v) {}
71
72     // Flattenable protocol
73     size_t getFlattenedSize() const { return sizeof(value); }
74     size_t getFdCount() const { return 0; }
75     status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
76         FlattenableUtils::write(buffer, size, value);
77         return NO_ERROR;
78     }
79     status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
80         FlattenableUtils::read(buffer, size, value);
81         return NO_ERROR;
82     }
83
84     int32_t value = 0;
85 };
86
87 struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
88     TestLightFlattenable() = default;
89     explicit TestLightFlattenable(int32_t v) : value(v) {}
90     int32_t value = 0;
91 };
92
93 class ExitOnDeath : public IBinder::DeathRecipient {
94 public:
95     ~ExitOnDeath() override = default;
96
97     void binderDied(const wp<IBinder>& /*who*/) override {
98         ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
99         exit(0);
100     }
101 };
102
103 // This callback class is used to test both one-way transactions and that sp<IInterface> can be
104 // passed correctly
105 class ICallback : public IInterface {
106 public:
107     DECLARE_META_INTERFACE(Callback)
108
109     enum class Tag : uint32_t {
110         OnCallback = IBinder::FIRST_CALL_TRANSACTION,
111         Last,
112     };
113
114     virtual void onCallback(int32_t aPlusOne) = 0;
115 };
116
117 class BpCallback : public SafeBpInterface<ICallback> {
118 public:
119     explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
120
121     void onCallback(int32_t aPlusOne) override {
122         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
123         return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
124     }
125
126 private:
127     static constexpr const char* getLogTag() { return "BpCallback"; }
128 };
129
130 #pragma clang diagnostic push
131 #pragma clang diagnostic ignored "-Wexit-time-destructors"
132 IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback");
133 #pragma clang diagnostic pop
134
135 class BnCallback : public SafeBnInterface<ICallback> {
136 public:
137     BnCallback() : SafeBnInterface("BnCallback") {}
138
139     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
140                         uint32_t /*flags*/) override {
141         EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
142         EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
143         ICallback::Tag tag = static_cast<ICallback::Tag>(code);
144         switch (tag) {
145             case ICallback::Tag::OnCallback: {
146                 return callLocalAsync(data, reply, &ICallback::onCallback);
147             }
148             case ICallback::Tag::Last:
149                 // Should not be possible because of the asserts at the beginning of the method
150                 [&]() { FAIL(); }();
151                 return UNKNOWN_ERROR;
152         }
153     }
154 };
155
156 class ISafeInterfaceTest : public IInterface {
157 public:
158     DECLARE_META_INTERFACE(SafeInterfaceTest)
159
160     enum class Tag : uint32_t {
161         SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
162         ReturnsNoMemory,
163         LogicalNot,
164         IncrementFlattenable,
165         IncrementLightFlattenable,
166         IncrementNoCopyNoMove,
167         ToUpper,
168         CallMeBack,
169         IncrementInt32,
170         IncrementUint32,
171         IncrementInt64,
172         IncrementUint64,
173         IncrementTwo,
174         Last,
175     };
176
177     // This is primarily so that the remote service dies when the test does, but it also serves to
178     // test the handling of sp<IBinder> and non-const methods
179     virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
180
181     // This is the most basic test since it doesn't require parceling any arguments
182     virtual status_t returnsNoMemory() const = 0;
183
184     // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
185     virtual status_t logicalNot(bool a, bool* notA) const = 0;
186     virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
187     virtual status_t increment(const TestLightFlattenable& a,
188                                TestLightFlattenable* aPlusOne) const = 0;
189     virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
190     virtual status_t toUpper(const String8& str, String8* upperStr) const = 0;
191     // As mentioned above, sp<IBinder> is already tested by setDeathToken
192     virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
193     virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
194     virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
195     virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
196     virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
197
198     // This tests that input/output parameter interleaving works correctly
199     virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
200                                int32_t* bPlusOne) const = 0;
201 };
202
203 class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
204 public:
205     explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
206           : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
207
208     status_t setDeathToken(const sp<IBinder>& token) override {
209         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
210         return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
211     }
212     status_t returnsNoMemory() const override {
213         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
214         return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
215     }
216     status_t logicalNot(bool a, bool* notA) const override {
217         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
218         return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
219     }
220     status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
221         using Signature =
222                 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
223         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
224         return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
225     }
226     status_t increment(const TestLightFlattenable& a,
227                        TestLightFlattenable* aPlusOne) const override {
228         using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
229                                                            TestLightFlattenable*) const;
230         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
231         return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
232     }
233     status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
234         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
235         using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
236                                                            NoCopyNoMove* aPlusOne) const;
237         return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
238     }
239     status_t toUpper(const String8& str, String8* upperStr) const override {
240         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
241         return callRemote<decltype(&ISafeInterfaceTest::toUpper)>(Tag::ToUpper, str, upperStr);
242     }
243     void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
244         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
245         return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
246                                                                           a);
247     }
248     status_t increment(int32_t a, int32_t* aPlusOne) const override {
249         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
250         using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
251         return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
252     }
253     status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
254         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
255         using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
256         return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
257     }
258     status_t increment(int64_t a, int64_t* aPlusOne) const override {
259         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
260         using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
261         return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
262     }
263     status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
264         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
265         using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
266         return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
267     }
268     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
269         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
270         using Signature =
271                 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
272         return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
273     }
274
275 private:
276     static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
277 };
278
279 #pragma clang diagnostic push
280 #pragma clang diagnostic ignored "-Wexit-time-destructors"
281 IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest");
282
283 static sp<IBinder::DeathRecipient> getDeathRecipient() {
284     static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
285     return recipient;
286 }
287 #pragma clang diagnostic pop
288
289 class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
290 public:
291     BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
292
293     status_t setDeathToken(const sp<IBinder>& token) override {
294         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
295         token->linkToDeath(getDeathRecipient());
296         return NO_ERROR;
297     }
298     status_t returnsNoMemory() const override {
299         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
300         return NO_MEMORY;
301     }
302     status_t logicalNot(bool a, bool* notA) const override {
303         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
304         *notA = !a;
305         return NO_ERROR;
306     }
307     status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
308         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
309         aPlusOne->value = a.value + 1;
310         return NO_ERROR;
311     }
312     status_t increment(const TestLightFlattenable& a,
313                        TestLightFlattenable* aPlusOne) const override {
314         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
315         aPlusOne->value = a.value + 1;
316         return NO_ERROR;
317     }
318     status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
319         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
320         aPlusOne->setValue(a.getValue() + 1);
321         return NO_ERROR;
322     }
323     status_t toUpper(const String8& str, String8* upperStr) const override {
324         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
325         *upperStr = str;
326         upperStr->toUpper();
327         return NO_ERROR;
328     }
329     void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
330         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
331         callback->onCallback(a + 1);
332     }
333     status_t increment(int32_t a, int32_t* aPlusOne) const override {
334         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
335         *aPlusOne = a + 1;
336         return NO_ERROR;
337     }
338     status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
339         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
340         *aPlusOne = a + 1;
341         return NO_ERROR;
342     }
343     status_t increment(int64_t a, int64_t* aPlusOne) const override {
344         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
345         *aPlusOne = a + 1;
346         return NO_ERROR;
347     }
348     status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
349         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
350         *aPlusOne = a + 1;
351         return NO_ERROR;
352     }
353     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
354         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
355         *aPlusOne = a + 1;
356         *bPlusOne = b + 1;
357         return NO_ERROR;
358     }
359
360     // BnInterface
361     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
362                         uint32_t /*flags*/) override {
363         EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
364         EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
365         ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
366         switch (tag) {
367             case ISafeInterfaceTest::Tag::SetDeathToken: {
368                 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
369             }
370             case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
371                 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
372             }
373             case ISafeInterfaceTest::Tag::LogicalNot: {
374                 return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
375             }
376             case ISafeInterfaceTest::Tag::IncrementFlattenable: {
377                 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
378                                                                    TestFlattenable* aPlusOne) const;
379                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
380             }
381             case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
382                 using Signature =
383                         status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
384                                                          TestLightFlattenable* aPlusOne) const;
385                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
386             }
387             case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
388                 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
389                                                                    NoCopyNoMove* aPlusOne) const;
390                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
391             }
392             case ISafeInterfaceTest::Tag::ToUpper: {
393                 return callLocal(data, reply, &ISafeInterfaceTest::toUpper);
394             }
395             case ISafeInterfaceTest::Tag::CallMeBack: {
396                 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
397             }
398             case ISafeInterfaceTest::Tag::IncrementInt32: {
399                 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
400                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
401             }
402             case ISafeInterfaceTest::Tag::IncrementUint32: {
403                 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
404                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
405             }
406             case ISafeInterfaceTest::Tag::IncrementInt64: {
407                 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
408                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
409             }
410             case ISafeInterfaceTest::Tag::IncrementUint64: {
411                 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
412                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
413             }
414             case ISafeInterfaceTest::Tag::IncrementTwo: {
415                 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
416                                                                    int32_t*) const;
417                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
418             }
419             case ISafeInterfaceTest::Tag::Last:
420                 // Should not be possible because of the asserts at the beginning of the method
421                 [&]() { FAIL(); }();
422                 return UNKNOWN_ERROR;
423         }
424     }
425
426 private:
427     static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
428 };
429
430 class SafeInterfaceTest : public ::testing::Test {
431 public:
432     SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
433         ProcessState::self()->startThreadPool();
434     }
435     ~SafeInterfaceTest() override = default;
436
437 protected:
438     sp<ISafeInterfaceTest> mSafeInterfaceTest;
439
440 private:
441     static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
442
443     sp<ISafeInterfaceTest> getRemoteService() {
444 #pragma clang diagnostic push
445 #pragma clang diagnostic ignored "-Wexit-time-destructors"
446         static std::mutex sMutex;
447         static sp<ISafeInterfaceTest> sService;
448         static sp<IBinder> sDeathToken = new BBinder;
449 #pragma clang diagnostic pop
450
451         std::unique_lock<decltype(sMutex)> lock;
452         if (sService == nullptr) {
453             ALOG(LOG_INFO, getLogTag(), "Forking remote process");
454             pid_t forkPid = fork();
455             EXPECT_NE(forkPid, -1);
456
457             const String16 serviceName("SafeInterfaceTest");
458
459             if (forkPid == 0) {
460                 ALOG(LOG_INFO, getLogTag(), "Remote process checking in");
461                 sp<ISafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
462                 defaultServiceManager()->addService(serviceName,
463                                                     IInterface::asBinder(nativeService));
464                 ProcessState::self()->startThreadPool();
465                 IPCThreadState::self()->joinThreadPool();
466                 // We shouldn't get to this point
467                 [&]() { FAIL(); }();
468             }
469
470             sp<IBinder> binder = defaultServiceManager()->getService(serviceName);
471             sService = interface_cast<ISafeInterfaceTest>(binder);
472             EXPECT_TRUE(sService != nullptr);
473
474             sService->setDeathToken(sDeathToken);
475         }
476
477         return sService;
478     }
479 };
480
481 TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
482     status_t result = mSafeInterfaceTest->returnsNoMemory();
483     ASSERT_EQ(NO_MEMORY, result);
484 }
485
486 TEST_F(SafeInterfaceTest, TestLogicalNot) {
487     const bool a = true;
488     bool notA = true;
489     status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
490     ASSERT_EQ(NO_ERROR, result);
491     ASSERT_EQ(!a, notA);
492     // Test both since we don't want to accidentally catch a default false somewhere
493     const bool b = false;
494     bool notB = false;
495     result = mSafeInterfaceTest->logicalNot(b, &notB);
496     ASSERT_EQ(NO_ERROR, result);
497     ASSERT_EQ(!b, notB);
498 }
499
500 TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
501     const TestFlattenable a{1};
502     TestFlattenable aPlusOne{0};
503     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
504     ASSERT_EQ(NO_ERROR, result);
505     ASSERT_EQ(a.value + 1, aPlusOne.value);
506 }
507
508 TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
509     const TestLightFlattenable a{1};
510     TestLightFlattenable aPlusOne{0};
511     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
512     ASSERT_EQ(NO_ERROR, result);
513     ASSERT_EQ(a.value + 1, aPlusOne.value);
514 }
515
516 TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
517     const NoCopyNoMove a{1};
518     NoCopyNoMove aPlusOne{0};
519     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
520     ASSERT_EQ(NO_ERROR, result);
521     ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
522 }
523
524 TEST_F(SafeInterfaceTest, TestToUpper) {
525     const String8 str{"Hello, world!"};
526     String8 upperStr;
527     status_t result = mSafeInterfaceTest->toUpper(str, &upperStr);
528     ASSERT_EQ(NO_ERROR, result);
529     ASSERT_TRUE(upperStr == String8{"HELLO, WORLD!"});
530 }
531
532 TEST_F(SafeInterfaceTest, TestCallMeBack) {
533     class CallbackReceiver : public BnCallback {
534     public:
535         void onCallback(int32_t aPlusOne) override {
536             ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
537             std::unique_lock<decltype(mMutex)> lock(mMutex);
538             mValue = aPlusOne;
539             mCondition.notify_one();
540         }
541
542         std::optional<int32_t> waitForCallback() {
543             std::unique_lock<decltype(mMutex)> lock(mMutex);
544             bool success =
545                     mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
546             return success ? mValue : std::nullopt;
547         }
548
549     private:
550         std::mutex mMutex;
551         std::condition_variable mCondition;
552         std::optional<int32_t> mValue;
553     };
554
555     sp<CallbackReceiver> receiver = new CallbackReceiver;
556     const int32_t a = 1;
557     mSafeInterfaceTest->callMeBack(receiver, a);
558     auto result = receiver->waitForCallback();
559     ASSERT_TRUE(result);
560     ASSERT_EQ(a + 1, *result);
561 }
562
563 TEST_F(SafeInterfaceTest, TestIncrementInt32) {
564     const int32_t a = 1;
565     int32_t aPlusOne = 0;
566     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
567     ASSERT_EQ(NO_ERROR, result);
568     ASSERT_EQ(a + 1, aPlusOne);
569 }
570
571 TEST_F(SafeInterfaceTest, TestIncrementUint32) {
572     const uint32_t a = 1;
573     uint32_t aPlusOne = 0;
574     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
575     ASSERT_EQ(NO_ERROR, result);
576     ASSERT_EQ(a + 1, aPlusOne);
577 }
578
579 TEST_F(SafeInterfaceTest, TestIncrementInt64) {
580     const int64_t a = 1;
581     int64_t aPlusOne = 0;
582     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
583     ASSERT_EQ(NO_ERROR, result);
584     ASSERT_EQ(a + 1, aPlusOne);
585 }
586
587 TEST_F(SafeInterfaceTest, TestIncrementUint64) {
588     const uint64_t a = 1;
589     uint64_t aPlusOne = 0;
590     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
591     ASSERT_EQ(NO_ERROR, result);
592     ASSERT_EQ(a + 1, aPlusOne);
593 }
594
595 TEST_F(SafeInterfaceTest, TestIncrementTwo) {
596     const int32_t a = 1;
597     int32_t aPlusOne = 0;
598     const int32_t b = 2;
599     int32_t bPlusOne = 0;
600     status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
601     ASSERT_EQ(NO_ERROR, result);
602     ASSERT_EQ(a + 1, aPlusOne);
603     ASSERT_EQ(b + 1, bPlusOne);
604 }
605
606 } // namespace tests
607 } // namespace android