2 * Copyright 2016 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <binder/SafeInterface.h>
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>
26 #pragma clang diagnostic push
27 #pragma clang diagnostic ignored "-Weverything"
28 #include <gtest/gtest.h>
29 #pragma clang diagnostic pop
33 using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
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 {
44 NoCopyNoMove() = default;
45 explicit NoCopyNoMove(int32_t value) : mValue(value) {}
46 ~NoCopyNoMove() override = default;
49 NoCopyNoMove(const NoCopyNoMove&) = delete;
50 NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
53 NoCopyNoMove(NoCopyNoMove&&) = delete;
54 NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
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); }
60 int32_t getValue() const { return mValue; }
61 void setValue(int32_t value) { mValue = value; }
65 uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
68 struct TestFlattenable : Flattenable<TestFlattenable> {
69 TestFlattenable() = default;
70 explicit TestFlattenable(int32_t v) : value(v) {}
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);
79 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
80 FlattenableUtils::read(buffer, size, value);
87 struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
88 TestLightFlattenable() = default;
89 explicit TestLightFlattenable(int32_t v) : value(v) {}
93 class ExitOnDeath : public IBinder::DeathRecipient {
95 ~ExitOnDeath() override = default;
97 void binderDied(const wp<IBinder>& /*who*/) override {
98 ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
103 // This callback class is used to test both one-way transactions and that sp<IInterface> can be
105 class ICallback : public IInterface {
107 DECLARE_META_INTERFACE(Callback)
109 enum class Tag : uint32_t {
110 OnCallback = IBinder::FIRST_CALL_TRANSACTION,
114 virtual void onCallback(int32_t aPlusOne) = 0;
117 class BpCallback : public SafeBpInterface<ICallback> {
119 explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
121 void onCallback(int32_t aPlusOne) override {
122 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
123 return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
127 static constexpr const char* getLogTag() { return "BpCallback"; }
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
135 class BnCallback : public SafeBnInterface<ICallback> {
137 BnCallback() : SafeBnInterface("BnCallback") {}
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);
145 case ICallback::Tag::OnCallback: {
146 return callLocalAsync(data, reply, &ICallback::onCallback);
148 case ICallback::Tag::Last:
149 // Should not be possible because of the asserts at the beginning of the method
151 return UNKNOWN_ERROR;
156 class ISafeInterfaceTest : public IInterface {
158 DECLARE_META_INTERFACE(SafeInterfaceTest)
160 enum class Tag : uint32_t {
161 SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
164 IncrementFlattenable,
165 IncrementLightFlattenable,
166 IncrementNoCopyNoMove,
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;
181 // This is the most basic test since it doesn't require parceling any arguments
182 virtual status_t returnsNoMemory() const = 0;
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;
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;
203 class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
205 explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
206 : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
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);
212 status_t returnsNoMemory() const override {
213 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
214 return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
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);
220 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
222 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
223 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
224 return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
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);
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);
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);
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,
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);
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);
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);
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);
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__);
271 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
272 return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
276 static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
279 #pragma clang diagnostic push
280 #pragma clang diagnostic ignored "-Wexit-time-destructors"
281 IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest");
283 static sp<IBinder::DeathRecipient> getDeathRecipient() {
284 static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
287 #pragma clang diagnostic pop
289 class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
291 BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
293 status_t setDeathToken(const sp<IBinder>& token) override {
294 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
295 token->linkToDeath(getDeathRecipient());
298 status_t returnsNoMemory() const override {
299 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
302 status_t logicalNot(bool a, bool* notA) const override {
303 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
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;
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;
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);
323 status_t toUpper(const String8& str, String8* upperStr) const override {
324 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
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);
333 status_t increment(int32_t a, int32_t* aPlusOne) const override {
334 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
338 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
339 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
343 status_t increment(int64_t a, int64_t* aPlusOne) const override {
344 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
348 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
349 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
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__);
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);
367 case ISafeInterfaceTest::Tag::SetDeathToken: {
368 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
370 case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
371 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
373 case ISafeInterfaceTest::Tag::LogicalNot: {
374 return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
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);
381 case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
383 status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
384 TestLightFlattenable* aPlusOne) const;
385 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
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);
392 case ISafeInterfaceTest::Tag::ToUpper: {
393 return callLocal(data, reply, &ISafeInterfaceTest::toUpper);
395 case ISafeInterfaceTest::Tag::CallMeBack: {
396 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
398 case ISafeInterfaceTest::Tag::IncrementInt32: {
399 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
400 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
402 case ISafeInterfaceTest::Tag::IncrementUint32: {
403 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
404 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
406 case ISafeInterfaceTest::Tag::IncrementInt64: {
407 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
408 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
410 case ISafeInterfaceTest::Tag::IncrementUint64: {
411 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
412 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
414 case ISafeInterfaceTest::Tag::IncrementTwo: {
415 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
417 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
419 case ISafeInterfaceTest::Tag::Last:
420 // Should not be possible because of the asserts at the beginning of the method
422 return UNKNOWN_ERROR;
427 static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
430 class SafeInterfaceTest : public ::testing::Test {
432 SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
433 ProcessState::self()->startThreadPool();
435 ~SafeInterfaceTest() override = default;
438 sp<ISafeInterfaceTest> mSafeInterfaceTest;
441 static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
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
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);
457 const String16 serviceName("SafeInterfaceTest");
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
470 sp<IBinder> binder = defaultServiceManager()->getService(serviceName);
471 sService = interface_cast<ISafeInterfaceTest>(binder);
472 EXPECT_TRUE(sService != nullptr);
474 sService->setDeathToken(sDeathToken);
481 TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
482 status_t result = mSafeInterfaceTest->returnsNoMemory();
483 ASSERT_EQ(NO_MEMORY, result);
486 TEST_F(SafeInterfaceTest, TestLogicalNot) {
489 status_t result = mSafeInterfaceTest->logicalNot(a, ¬A);
490 ASSERT_EQ(NO_ERROR, result);
492 // Test both since we don't want to accidentally catch a default false somewhere
493 const bool b = false;
495 result = mSafeInterfaceTest->logicalNot(b, ¬B);
496 ASSERT_EQ(NO_ERROR, result);
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);
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);
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());
524 TEST_F(SafeInterfaceTest, TestToUpper) {
525 const String8 str{"Hello, world!"};
527 status_t result = mSafeInterfaceTest->toUpper(str, &upperStr);
528 ASSERT_EQ(NO_ERROR, result);
529 ASSERT_TRUE(upperStr == String8{"HELLO, WORLD!"});
532 TEST_F(SafeInterfaceTest, TestCallMeBack) {
533 class CallbackReceiver : public BnCallback {
535 void onCallback(int32_t aPlusOne) override {
536 ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
537 std::unique_lock<decltype(mMutex)> lock(mMutex);
539 mCondition.notify_one();
542 std::optional<int32_t> waitForCallback() {
543 std::unique_lock<decltype(mMutex)> lock(mMutex);
545 mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
546 return success ? mValue : std::nullopt;
551 std::condition_variable mCondition;
552 std::optional<int32_t> mValue;
555 sp<CallbackReceiver> receiver = new CallbackReceiver;
557 mSafeInterfaceTest->callMeBack(receiver, a);
558 auto result = receiver->waitForCallback();
560 ASSERT_EQ(a + 1, *result);
563 TEST_F(SafeInterfaceTest, TestIncrementInt32) {
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);
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);
579 TEST_F(SafeInterfaceTest, TestIncrementInt64) {
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);
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);
595 TEST_F(SafeInterfaceTest, TestIncrementTwo) {
597 int32_t aPlusOne = 0;
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);
607 } // namespace android