blob: 849dc7c4d585b11753c11f22df8b2564f96c17dc [file] [log] [blame]
Dan Stozad630e522016-12-01 15:16:31 -08001/*
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
Tomasz Wasilczyk300aa132023-10-26 15:00:04 -070031#include <utils/Flattenable.h>
Dan Stoza6dd325b2017-04-07 14:31:51 -070032#include <utils/LightRefBase.h>
Dan Stoza2537db72017-04-07 16:32:38 -070033#include <utils/NativeHandle.h>
34
35#include <cutils/native_handle.h>
Dan Stoza6dd325b2017-04-07 14:31:51 -070036
Dan Stozad630e522016-12-01 15:16:31 -080037#include <optional>
38
Steven Moreland56044032023-05-24 19:31:25 +000039#include <inttypes.h>
Dan Stoza2537db72017-04-07 16:32:38 -070040#include <sys/eventfd.h>
Steven Morelandcde5d532020-12-02 23:34:15 +000041#include <sys/prctl.h>
Dan Stoza2537db72017-04-07 16:32:38 -070042
Jim Shargo7693c4a2024-10-11 02:28:18 +000043#include <gmock/gmock.h>
44
Dan Stozad630e522016-12-01 15:16:31 -080045using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -070046using android::binder::unique_fd;
Dan Stozad630e522016-12-01 15:16:31 -080047
48namespace android {
49namespace tests {
50
Steven Morelandcde5d532020-12-02 23:34:15 +000051static const String16 kServiceName("SafeInterfaceTest");
52
Dan Stoza81ea3ef2017-04-07 15:00:18 -070053enum class TestEnum : uint32_t {
54 INVALID = 0,
55 INITIAL = 1,
56 FINAL = 2,
57};
58
Dan Stozad630e522016-12-01 15:16:31 -080059// This class serves two purposes:
60// 1) It ensures that the implementation doesn't require copying or moving the data (for
61// efficiency purposes)
62// 2) It tests that Parcelables can be passed correctly
63class NoCopyNoMove : public Parcelable {
64public:
65 NoCopyNoMove() = default;
66 explicit NoCopyNoMove(int32_t value) : mValue(value) {}
67 ~NoCopyNoMove() override = default;
68
69 // Not copyable
70 NoCopyNoMove(const NoCopyNoMove&) = delete;
71 NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
72
73 // Not movable
74 NoCopyNoMove(NoCopyNoMove&&) = delete;
75 NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
76
77 // Parcelable interface
78 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
79 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
80
81 int32_t getValue() const { return mValue; }
82 void setValue(int32_t value) { mValue = value; }
83
84private:
85 int32_t mValue = 0;
Steven Moreland573adc12019-07-17 13:29:06 -070086 __attribute__((unused)) uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
Dan Stozad630e522016-12-01 15:16:31 -080087};
88
Dan Stozadf614ae2017-03-28 17:02:05 -070089struct TestFlattenable : Flattenable<TestFlattenable> {
90 TestFlattenable() = default;
91 explicit TestFlattenable(int32_t v) : value(v) {}
92
93 // Flattenable protocol
94 size_t getFlattenedSize() const { return sizeof(value); }
95 size_t getFdCount() const { return 0; }
96 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
97 FlattenableUtils::write(buffer, size, value);
98 return NO_ERROR;
99 }
100 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
101 FlattenableUtils::read(buffer, size, value);
102 return NO_ERROR;
103 }
104
105 int32_t value = 0;
106};
107
Dan Stozad630e522016-12-01 15:16:31 -0800108struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
109 TestLightFlattenable() = default;
110 explicit TestLightFlattenable(int32_t v) : value(v) {}
111 int32_t value = 0;
112};
113
Dan Stoza6dd325b2017-04-07 14:31:51 -0700114// It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
115// but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
116// base class
117class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
118 public LightRefBase<TestLightRefBaseFlattenable> {
119public:
120 TestLightRefBaseFlattenable() = default;
121 explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
122
123 // Flattenable protocol
124 size_t getFlattenedSize() const { return sizeof(value); }
125 size_t getFdCount() const { return 0; }
126 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
127 FlattenableUtils::write(buffer, size, value);
128 return NO_ERROR;
129 }
130 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
131 FlattenableUtils::read(buffer, size, value);
132 return NO_ERROR;
133 }
134
135 int32_t value = 0;
136};
137
Dan Stoza1af8a882017-04-10 13:28:54 -0700138class TestParcelable : public Parcelable {
139public:
140 TestParcelable() = default;
141 explicit TestParcelable(int32_t value) : mValue(value) {}
142 TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
143 TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
144
145 // Parcelable interface
146 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
147 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
148
149 int32_t getValue() const { return mValue; }
150 void setValue(int32_t value) { mValue = value; }
151
152private:
153 int32_t mValue = 0;
154};
155
Dan Stozad630e522016-12-01 15:16:31 -0800156class ExitOnDeath : public IBinder::DeathRecipient {
157public:
158 ~ExitOnDeath() override = default;
159
160 void binderDied(const wp<IBinder>& /*who*/) override {
161 ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
162 exit(0);
163 }
164};
165
166// This callback class is used to test both one-way transactions and that sp<IInterface> can be
167// passed correctly
168class ICallback : public IInterface {
169public:
170 DECLARE_META_INTERFACE(Callback)
171
172 enum class Tag : uint32_t {
173 OnCallback = IBinder::FIRST_CALL_TRANSACTION,
174 Last,
175 };
176
177 virtual void onCallback(int32_t aPlusOne) = 0;
178};
179
180class BpCallback : public SafeBpInterface<ICallback> {
181public:
182 explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
183
184 void onCallback(int32_t aPlusOne) override {
185 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
186 return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
187 }
188
189private:
190 static constexpr const char* getLogTag() { return "BpCallback"; }
191};
192
193#pragma clang diagnostic push
194#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900195IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback")
Dan Stozad630e522016-12-01 15:16:31 -0800196#pragma clang diagnostic pop
197
198class BnCallback : public SafeBnInterface<ICallback> {
199public:
200 BnCallback() : SafeBnInterface("BnCallback") {}
201
202 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
203 uint32_t /*flags*/) override {
204 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
205 EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
206 ICallback::Tag tag = static_cast<ICallback::Tag>(code);
207 switch (tag) {
208 case ICallback::Tag::OnCallback: {
209 return callLocalAsync(data, reply, &ICallback::onCallback);
210 }
211 case ICallback::Tag::Last:
212 // Should not be possible because of the asserts at the beginning of the method
213 [&]() { FAIL(); }();
214 return UNKNOWN_ERROR;
215 }
216 }
217};
218
219class ISafeInterfaceTest : public IInterface {
220public:
221 DECLARE_META_INTERFACE(SafeInterfaceTest)
222
223 enum class Tag : uint32_t {
224 SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
225 ReturnsNoMemory,
226 LogicalNot,
Jim Shargo7693c4a2024-10-11 02:28:18 +0000227 LogicalNotVector,
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700228 ModifyEnum,
Dan Stozadf614ae2017-03-28 17:02:05 -0700229 IncrementFlattenable,
Dan Stozad630e522016-12-01 15:16:31 -0800230 IncrementLightFlattenable,
Dan Stoza6dd325b2017-04-07 14:31:51 -0700231 IncrementLightRefBaseFlattenable,
Dan Stoza2537db72017-04-07 16:32:38 -0700232 IncrementNativeHandle,
Dan Stozad630e522016-12-01 15:16:31 -0800233 IncrementNoCopyNoMove,
Dan Stoza1af8a882017-04-10 13:28:54 -0700234 IncrementParcelableVector,
Elliott Hughesd7657972021-04-12 15:31:22 -0700235 DoubleString,
Dan Stozad630e522016-12-01 15:16:31 -0800236 CallMeBack,
237 IncrementInt32,
238 IncrementUint32,
Dan Stoza662a8992017-04-06 16:18:39 -0700239 IncrementInt64,
240 IncrementUint64,
Dan Stoza4c6d9732018-11-14 10:18:14 -0800241 IncrementFloat,
Dan Stozad630e522016-12-01 15:16:31 -0800242 IncrementTwo,
243 Last,
244 };
245
246 // This is primarily so that the remote service dies when the test does, but it also serves to
247 // test the handling of sp<IBinder> and non-const methods
248 virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
249
250 // This is the most basic test since it doesn't require parceling any arguments
251 virtual status_t returnsNoMemory() const = 0;
252
253 // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
254 virtual status_t logicalNot(bool a, bool* notA) const = 0;
Jim Shargo7693c4a2024-10-11 02:28:18 +0000255 virtual status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const = 0;
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700256 virtual status_t modifyEnum(TestEnum a, TestEnum* b) const = 0;
Dan Stozadf614ae2017-03-28 17:02:05 -0700257 virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800258 virtual status_t increment(const TestLightFlattenable& a,
259 TestLightFlattenable* aPlusOne) const = 0;
Dan Stoza6dd325b2017-04-07 14:31:51 -0700260 virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
261 sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
Dan Stoza2537db72017-04-07 16:32:38 -0700262 virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800263 virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
Dan Stoza1af8a882017-04-10 13:28:54 -0700264 virtual status_t increment(const std::vector<TestParcelable>& a,
265 std::vector<TestParcelable>* aPlusOne) const = 0;
Elliott Hughesd7657972021-04-12 15:31:22 -0700266 virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800267 // As mentioned above, sp<IBinder> is already tested by setDeathToken
268 virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
269 virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
270 virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
Dan Stoza662a8992017-04-06 16:18:39 -0700271 virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
272 virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
Dan Stoza4c6d9732018-11-14 10:18:14 -0800273 virtual status_t increment(float a, float* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800274
275 // This tests that input/output parameter interleaving works correctly
276 virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
277 int32_t* bPlusOne) const = 0;
278};
279
280class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
281public:
282 explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
283 : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
284
285 status_t setDeathToken(const sp<IBinder>& token) override {
286 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
287 return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
288 }
289 status_t returnsNoMemory() const override {
290 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
291 return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
292 }
293 status_t logicalNot(bool a, bool* notA) const override {
294 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Jim Shargo7693c4a2024-10-11 02:28:18 +0000295 using Signature = status_t (ISafeInterfaceTest::*)(bool, bool*) const;
296 return callRemote<Signature>(Tag::LogicalNot, a, notA);
297 }
298 status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override {
299 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
300 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>&,
301 std::vector<bool>*) const;
302 return callRemote<Signature>(Tag::LogicalNotVector, a, notA);
Dan Stozad630e522016-12-01 15:16:31 -0800303 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700304 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
305 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
306 return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b);
307 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700308 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
309 using Signature =
310 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
311 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
312 return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
313 }
Dan Stozad630e522016-12-01 15:16:31 -0800314 status_t increment(const TestLightFlattenable& a,
315 TestLightFlattenable* aPlusOne) const override {
316 using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
317 TestLightFlattenable*) const;
318 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
319 return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
320 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700321 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
322 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
323 using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
324 sp<TestLightRefBaseFlattenable>*) const;
325 return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
326 }
Dan Stoza2537db72017-04-07 16:32:38 -0700327 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
328 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
329 using Signature =
330 status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&, sp<NativeHandle>*) const;
331 return callRemote<Signature>(Tag::IncrementNativeHandle, a, aPlusOne);
332 }
Dan Stozad630e522016-12-01 15:16:31 -0800333 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
334 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
335 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
336 NoCopyNoMove* aPlusOne) const;
337 return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
338 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700339 status_t increment(const std::vector<TestParcelable>& a,
340 std::vector<TestParcelable>* aPlusOne) const override {
341 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
342 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
343 std::vector<TestParcelable>*);
344 return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
345 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700346 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800347 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700348 return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
349 doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800350 }
351 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
352 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
353 return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
354 a);
355 }
356 status_t increment(int32_t a, int32_t* aPlusOne) const override {
357 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
358 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
359 return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
360 }
361 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
362 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
363 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
364 return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
365 }
Dan Stoza662a8992017-04-06 16:18:39 -0700366 status_t increment(int64_t a, int64_t* aPlusOne) const override {
367 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
368 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
369 return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
370 }
371 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
372 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
373 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
374 return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
375 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800376 status_t increment(float a, float* aPlusOne) const override {
377 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
378 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
379 return callRemote<Signature>(Tag::IncrementFloat, a, aPlusOne);
380 }
Dan Stozad630e522016-12-01 15:16:31 -0800381 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
382 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
383 using Signature =
384 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
385 return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
386 }
387
388private:
389 static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
390};
391
392#pragma clang diagnostic push
393#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900394IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest")
Dan Stozad630e522016-12-01 15:16:31 -0800395
396static sp<IBinder::DeathRecipient> getDeathRecipient() {
397 static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
398 return recipient;
399}
400#pragma clang diagnostic pop
401
402class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
403public:
404 BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
405
406 status_t setDeathToken(const sp<IBinder>& token) override {
407 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
408 token->linkToDeath(getDeathRecipient());
409 return NO_ERROR;
410 }
411 status_t returnsNoMemory() const override {
412 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
413 return NO_MEMORY;
414 }
415 status_t logicalNot(bool a, bool* notA) const override {
416 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
417 *notA = !a;
418 return NO_ERROR;
419 }
Jim Shargo7693c4a2024-10-11 02:28:18 +0000420 status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override {
421 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
422 notA->clear();
423 for (bool value : a) {
424 notA->push_back(!value);
425 }
426 return NO_ERROR;
427 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700428 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
429 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
430 *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID;
431 return NO_ERROR;
432 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700433 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
434 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
435 aPlusOne->value = a.value + 1;
436 return NO_ERROR;
437 }
Dan Stozad630e522016-12-01 15:16:31 -0800438 status_t increment(const TestLightFlattenable& a,
439 TestLightFlattenable* aPlusOne) const override {
440 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
441 aPlusOne->value = a.value + 1;
442 return NO_ERROR;
443 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700444 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
445 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
446 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
447 *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
448 return NO_ERROR;
449 }
Dan Stoza2537db72017-04-07 16:32:38 -0700450 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
451 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
452 native_handle* rawHandle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
453 if (rawHandle == nullptr) return NO_MEMORY;
454
455 // Copy the fd over directly
456 rawHandle->data[0] = dup(a->handle()->data[0]);
457
458 // Increment the int
459 rawHandle->data[1] = a->handle()->data[1] + 1;
460
461 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
462 // the native_handle when it goes out of scope
463 *aPlusOne = NativeHandle::create(rawHandle, true);
464 return NO_ERROR;
465 }
Dan Stozad630e522016-12-01 15:16:31 -0800466 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
467 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
468 aPlusOne->setValue(a.getValue() + 1);
469 return NO_ERROR;
470 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700471 status_t increment(const std::vector<TestParcelable>& a,
472 std::vector<TestParcelable>* aPlusOne) const override {
473 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
474 aPlusOne->resize(a.size());
475 for (size_t i = 0; i < a.size(); ++i) {
476 (*aPlusOne)[i].setValue(a[i].getValue() + 1);
477 }
478 return NO_ERROR;
479 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700480 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800481 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700482 *doubleStr = str + str;
Dan Stozad630e522016-12-01 15:16:31 -0800483 return NO_ERROR;
484 }
485 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
486 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
487 callback->onCallback(a + 1);
488 }
489 status_t increment(int32_t a, int32_t* aPlusOne) const override {
490 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
491 *aPlusOne = a + 1;
492 return NO_ERROR;
493 }
494 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
495 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
496 *aPlusOne = a + 1;
497 return NO_ERROR;
498 }
Dan Stoza662a8992017-04-06 16:18:39 -0700499 status_t increment(int64_t a, int64_t* aPlusOne) const override {
500 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
501 *aPlusOne = a + 1;
502 return NO_ERROR;
503 }
504 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
505 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
506 *aPlusOne = a + 1;
507 return NO_ERROR;
508 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800509 status_t increment(float a, float* aPlusOne) const override {
510 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
511 *aPlusOne = a + 1.0f;
512 return NO_ERROR;
513 }
Dan Stozad630e522016-12-01 15:16:31 -0800514 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
515 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
516 *aPlusOne = a + 1;
517 *bPlusOne = b + 1;
518 return NO_ERROR;
519 }
520
521 // BnInterface
522 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
523 uint32_t /*flags*/) override {
524 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
525 EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
526 ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
527 switch (tag) {
528 case ISafeInterfaceTest::Tag::SetDeathToken: {
529 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
530 }
531 case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
532 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
533 }
534 case ISafeInterfaceTest::Tag::LogicalNot: {
Jim Shargo7693c4a2024-10-11 02:28:18 +0000535 using Signature = status_t (ISafeInterfaceTest::*)(bool a, bool* notA) const;
536 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot);
537 }
538 case ISafeInterfaceTest::Tag::LogicalNotVector: {
539 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>& a,
540 std::vector<bool>* notA) const;
541 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot);
Dan Stozad630e522016-12-01 15:16:31 -0800542 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700543 case ISafeInterfaceTest::Tag::ModifyEnum: {
544 return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum);
545 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700546 case ISafeInterfaceTest::Tag::IncrementFlattenable: {
547 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
548 TestFlattenable* aPlusOne) const;
549 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
550 }
Dan Stozad630e522016-12-01 15:16:31 -0800551 case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
552 using Signature =
553 status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
554 TestLightFlattenable* aPlusOne) const;
555 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
556 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700557 case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
558 using Signature =
559 status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
560 sp<TestLightRefBaseFlattenable>*) const;
561 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
562 }
Dan Stoza2537db72017-04-07 16:32:38 -0700563 case ISafeInterfaceTest::Tag::IncrementNativeHandle: {
564 using Signature = status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&,
565 sp<NativeHandle>*) const;
566 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
567 }
Dan Stozad630e522016-12-01 15:16:31 -0800568 case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
569 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
570 NoCopyNoMove* aPlusOne) const;
571 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
572 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700573 case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
574 using Signature =
575 status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
576 std::vector<TestParcelable>*) const;
577 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
578 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700579 case ISafeInterfaceTest::Tag::DoubleString: {
580 return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
Dan Stozad630e522016-12-01 15:16:31 -0800581 }
582 case ISafeInterfaceTest::Tag::CallMeBack: {
583 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
584 }
585 case ISafeInterfaceTest::Tag::IncrementInt32: {
586 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
587 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
588 }
589 case ISafeInterfaceTest::Tag::IncrementUint32: {
590 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
591 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
592 }
Dan Stoza662a8992017-04-06 16:18:39 -0700593 case ISafeInterfaceTest::Tag::IncrementInt64: {
594 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
595 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
596 }
597 case ISafeInterfaceTest::Tag::IncrementUint64: {
598 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
599 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
600 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800601 case ISafeInterfaceTest::Tag::IncrementFloat: {
602 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
603 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
604 }
Dan Stozad630e522016-12-01 15:16:31 -0800605 case ISafeInterfaceTest::Tag::IncrementTwo: {
606 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
607 int32_t*) const;
608 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
609 }
610 case ISafeInterfaceTest::Tag::Last:
611 // Should not be possible because of the asserts at the beginning of the method
612 [&]() { FAIL(); }();
613 return UNKNOWN_ERROR;
614 }
615 }
616
617private:
618 static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
619};
620
621class SafeInterfaceTest : public ::testing::Test {
622public:
623 SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
624 ProcessState::self()->startThreadPool();
625 }
626 ~SafeInterfaceTest() override = default;
627
628protected:
629 sp<ISafeInterfaceTest> mSafeInterfaceTest;
630
631private:
632 static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
633
634 sp<ISafeInterfaceTest> getRemoteService() {
Tomasz Wasilczykbb07b982023-10-11 21:25:36 +0000635#pragma clang diagnostic push
636#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Steven Morelandcde5d532020-12-02 23:34:15 +0000637 sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
Tomasz Wasilczykbb07b982023-10-11 21:25:36 +0000638#pragma clang diagnostic pop
Steven Morelandcde5d532020-12-02 23:34:15 +0000639 sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
640 EXPECT_TRUE(iface != nullptr);
Dan Stozad630e522016-12-01 15:16:31 -0800641
Steven Morelandcde5d532020-12-02 23:34:15 +0000642 iface->setDeathToken(new BBinder);
Dan Stozad630e522016-12-01 15:16:31 -0800643
Steven Morelandcde5d532020-12-02 23:34:15 +0000644 return iface;
Dan Stozad630e522016-12-01 15:16:31 -0800645 }
646};
647
648TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
649 status_t result = mSafeInterfaceTest->returnsNoMemory();
650 ASSERT_EQ(NO_MEMORY, result);
651}
652
653TEST_F(SafeInterfaceTest, TestLogicalNot) {
654 const bool a = true;
655 bool notA = true;
656 status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
657 ASSERT_EQ(NO_ERROR, result);
658 ASSERT_EQ(!a, notA);
659 // Test both since we don't want to accidentally catch a default false somewhere
660 const bool b = false;
661 bool notB = false;
662 result = mSafeInterfaceTest->logicalNot(b, &notB);
663 ASSERT_EQ(NO_ERROR, result);
664 ASSERT_EQ(!b, notB);
665}
666
Jim Shargo7693c4a2024-10-11 02:28:18 +0000667TEST_F(SafeInterfaceTest, TestLogicalNotVector) {
668 const std::vector<bool> a = {true, false, true};
669 std::vector<bool> notA;
670 status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
671 ASSERT_EQ(NO_ERROR, result);
672 std::vector<bool> expected = {false, true, false};
673 ASSERT_THAT(notA, testing::ContainerEq(expected));
674}
675
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700676TEST_F(SafeInterfaceTest, TestModifyEnum) {
677 const TestEnum a = TestEnum::INITIAL;
678 TestEnum b = TestEnum::INVALID;
679 status_t result = mSafeInterfaceTest->modifyEnum(a, &b);
680 ASSERT_EQ(NO_ERROR, result);
681 ASSERT_EQ(TestEnum::FINAL, b);
682}
683
Dan Stozadf614ae2017-03-28 17:02:05 -0700684TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
685 const TestFlattenable a{1};
686 TestFlattenable aPlusOne{0};
687 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
688 ASSERT_EQ(NO_ERROR, result);
689 ASSERT_EQ(a.value + 1, aPlusOne.value);
690}
691
Dan Stozad630e522016-12-01 15:16:31 -0800692TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
693 const TestLightFlattenable a{1};
694 TestLightFlattenable aPlusOne{0};
695 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
696 ASSERT_EQ(NO_ERROR, result);
697 ASSERT_EQ(a.value + 1, aPlusOne.value);
698}
699
Dan Stoza6dd325b2017-04-07 14:31:51 -0700700TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
701 sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
702 sp<TestLightRefBaseFlattenable> aPlusOne;
703 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
704 ASSERT_EQ(NO_ERROR, result);
705 ASSERT_NE(nullptr, aPlusOne.get());
706 ASSERT_EQ(a->value + 1, aPlusOne->value);
707}
708
Dan Stoza2537db72017-04-07 16:32:38 -0700709namespace { // Anonymous namespace
710
711bool fdsAreEquivalent(int a, int b) {
712 struct stat statA {};
713 struct stat statB {};
714 if (fstat(a, &statA) != 0) return false;
715 if (fstat(b, &statB) != 0) return false;
716 return (statA.st_dev == statB.st_dev) && (statA.st_ino == statB.st_ino);
717}
718
719} // Anonymous namespace
720
721TEST_F(SafeInterfaceTest, TestIncrementNativeHandle) {
722 // Create an fd we can use to send and receive from the remote process
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700723 unique_fd eventFd{eventfd(0 /*initval*/, 0 /*flags*/)};
Dan Stoza2537db72017-04-07 16:32:38 -0700724 ASSERT_NE(-1, eventFd);
725
726 // Determine the maximum number of fds this process can have open
727 struct rlimit limit {};
728 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &limit));
Steven Moreland56044032023-05-24 19:31:25 +0000729 uint64_t maxFds = limit.rlim_cur;
730
731 ALOG(LOG_INFO, "SafeInterfaceTest", "%s max FDs: %" PRIu64, __PRETTY_FUNCTION__, maxFds);
Dan Stoza2537db72017-04-07 16:32:38 -0700732
733 // Perform this test enough times to rule out fd leaks
Steven Moreland56044032023-05-24 19:31:25 +0000734 for (uint32_t iter = 0; iter < (maxFds + 100); ++iter) {
Dan Stoza2537db72017-04-07 16:32:38 -0700735 native_handle* handle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
736 ASSERT_NE(nullptr, handle);
737 handle->data[0] = dup(eventFd.get());
738 handle->data[1] = 1;
739
740 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
741 // the native_handle when it goes out of scope
742 sp<NativeHandle> a = NativeHandle::create(handle, true);
743
744 sp<NativeHandle> aPlusOne;
745 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
746 ASSERT_EQ(NO_ERROR, result);
747 ASSERT_TRUE(fdsAreEquivalent(a->handle()->data[0], aPlusOne->handle()->data[0]));
748 ASSERT_EQ(a->handle()->data[1] + 1, aPlusOne->handle()->data[1]);
749 }
750}
751
Dan Stozad630e522016-12-01 15:16:31 -0800752TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
753 const NoCopyNoMove a{1};
754 NoCopyNoMove aPlusOne{0};
755 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
756 ASSERT_EQ(NO_ERROR, result);
757 ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
758}
759
Elliott Hughes01528732024-05-16 17:33:09 +0000760TEST_F(SafeInterfaceTest, TestIncrementParcelableVector) {
Dan Stoza1af8a882017-04-10 13:28:54 -0700761 const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
762 std::vector<TestParcelable> aPlusOne;
763 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
Steven Moreland573adc12019-07-17 13:29:06 -0700764 ASSERT_EQ(NO_ERROR, result);
Dan Stoza1af8a882017-04-10 13:28:54 -0700765 ASSERT_EQ(a.size(), aPlusOne.size());
766 for (size_t i = 0; i < a.size(); ++i) {
767 ASSERT_EQ(a[i].getValue() + 1, aPlusOne[i].getValue());
768 }
769}
770
Elliott Hughesd7657972021-04-12 15:31:22 -0700771TEST_F(SafeInterfaceTest, TestDoubleString) {
772 const String8 str{"asdf"};
773 String8 doubleStr;
774 status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800775 ASSERT_EQ(NO_ERROR, result);
Elliott Hughesd7657972021-04-12 15:31:22 -0700776 ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
Dan Stozad630e522016-12-01 15:16:31 -0800777}
778
779TEST_F(SafeInterfaceTest, TestCallMeBack) {
780 class CallbackReceiver : public BnCallback {
781 public:
782 void onCallback(int32_t aPlusOne) override {
783 ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
784 std::unique_lock<decltype(mMutex)> lock(mMutex);
785 mValue = aPlusOne;
786 mCondition.notify_one();
787 }
788
789 std::optional<int32_t> waitForCallback() {
790 std::unique_lock<decltype(mMutex)> lock(mMutex);
791 bool success =
792 mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
793 return success ? mValue : std::nullopt;
794 }
795
796 private:
797 std::mutex mMutex;
798 std::condition_variable mCondition;
799 std::optional<int32_t> mValue;
800 };
801
802 sp<CallbackReceiver> receiver = new CallbackReceiver;
803 const int32_t a = 1;
804 mSafeInterfaceTest->callMeBack(receiver, a);
805 auto result = receiver->waitForCallback();
806 ASSERT_TRUE(result);
807 ASSERT_EQ(a + 1, *result);
808}
809
810TEST_F(SafeInterfaceTest, TestIncrementInt32) {
811 const int32_t a = 1;
812 int32_t aPlusOne = 0;
813 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
814 ASSERT_EQ(NO_ERROR, result);
815 ASSERT_EQ(a + 1, aPlusOne);
816}
817
818TEST_F(SafeInterfaceTest, TestIncrementUint32) {
819 const uint32_t a = 1;
820 uint32_t aPlusOne = 0;
821 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
822 ASSERT_EQ(NO_ERROR, result);
823 ASSERT_EQ(a + 1, aPlusOne);
824}
825
Dan Stoza662a8992017-04-06 16:18:39 -0700826TEST_F(SafeInterfaceTest, TestIncrementInt64) {
827 const int64_t a = 1;
828 int64_t aPlusOne = 0;
829 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
830 ASSERT_EQ(NO_ERROR, result);
831 ASSERT_EQ(a + 1, aPlusOne);
832}
833
834TEST_F(SafeInterfaceTest, TestIncrementUint64) {
835 const uint64_t a = 1;
836 uint64_t aPlusOne = 0;
837 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
838 ASSERT_EQ(NO_ERROR, result);
839 ASSERT_EQ(a + 1, aPlusOne);
840}
841
Dan Stoza4c6d9732018-11-14 10:18:14 -0800842TEST_F(SafeInterfaceTest, TestIncrementFloat) {
843 const float a = 1.0f;
844 float aPlusOne = 0.0f;
845 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
846 ASSERT_EQ(NO_ERROR, result);
847 ASSERT_EQ(a + 1.0f, aPlusOne);
848}
849
Dan Stozad630e522016-12-01 15:16:31 -0800850TEST_F(SafeInterfaceTest, TestIncrementTwo) {
851 const int32_t a = 1;
852 int32_t aPlusOne = 0;
853 const int32_t b = 2;
854 int32_t bPlusOne = 0;
855 status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
856 ASSERT_EQ(NO_ERROR, result);
857 ASSERT_EQ(a + 1, aPlusOne);
858 ASSERT_EQ(b + 1, bPlusOne);
859}
860
Steven Morelandcde5d532020-12-02 23:34:15 +0000861extern "C" int main(int argc, char **argv) {
862 testing::InitGoogleTest(&argc, argv);
863
864 if (fork() == 0) {
865 prctl(PR_SET_PDEATHSIG, SIGHUP);
866 sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
867 status_t status = defaultServiceManager()->addService(kServiceName, nativeService);
868 if (status != OK) {
869 ALOG(LOG_INFO, "SafeInterfaceServer", "could not register");
870 return EXIT_FAILURE;
871 }
872 IPCThreadState::self()->joinThreadPool();
873 return EXIT_FAILURE;
874 }
875
876 return RUN_ALL_TESTS();
877}
878
Dan Stozad630e522016-12-01 15:16:31 -0800879} // namespace tests
880} // namespace android