blob: 5e8a32a61ba63e879162e85f0f272eb60989a031 [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
Dan Stoza6dd325b2017-04-07 14:31:51 -070031#include <utils/LightRefBase.h>
Dan Stoza2537db72017-04-07 16:32:38 -070032#include <utils/NativeHandle.h>
33
34#include <cutils/native_handle.h>
Dan Stoza6dd325b2017-04-07 14:31:51 -070035
Dan Stozad630e522016-12-01 15:16:31 -080036#include <optional>
37
Steven Moreland56044032023-05-24 19:31:25 +000038#include <inttypes.h>
Dan Stoza2537db72017-04-07 16:32:38 -070039#include <sys/eventfd.h>
Steven Morelandcde5d532020-12-02 23:34:15 +000040#include <sys/prctl.h>
Dan Stoza2537db72017-04-07 16:32:38 -070041
Dan Stozad630e522016-12-01 15:16:31 -080042using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
43
44namespace android {
45namespace tests {
46
Steven Morelandcde5d532020-12-02 23:34:15 +000047static const String16 kServiceName("SafeInterfaceTest");
48
Dan Stoza81ea3ef2017-04-07 15:00:18 -070049enum class TestEnum : uint32_t {
50 INVALID = 0,
51 INITIAL = 1,
52 FINAL = 2,
53};
54
Dan Stozad630e522016-12-01 15:16:31 -080055// This class serves two purposes:
56// 1) It ensures that the implementation doesn't require copying or moving the data (for
57// efficiency purposes)
58// 2) It tests that Parcelables can be passed correctly
59class NoCopyNoMove : public Parcelable {
60public:
61 NoCopyNoMove() = default;
62 explicit NoCopyNoMove(int32_t value) : mValue(value) {}
63 ~NoCopyNoMove() override = default;
64
65 // Not copyable
66 NoCopyNoMove(const NoCopyNoMove&) = delete;
67 NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
68
69 // Not movable
70 NoCopyNoMove(NoCopyNoMove&&) = delete;
71 NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
72
73 // Parcelable interface
74 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
75 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
76
77 int32_t getValue() const { return mValue; }
78 void setValue(int32_t value) { mValue = value; }
79
80private:
81 int32_t mValue = 0;
Steven Moreland573adc12019-07-17 13:29:06 -070082 __attribute__((unused)) uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
Dan Stozad630e522016-12-01 15:16:31 -080083};
84
Dan Stozadf614ae2017-03-28 17:02:05 -070085struct TestFlattenable : Flattenable<TestFlattenable> {
86 TestFlattenable() = default;
87 explicit TestFlattenable(int32_t v) : value(v) {}
88
89 // Flattenable protocol
90 size_t getFlattenedSize() const { return sizeof(value); }
91 size_t getFdCount() const { return 0; }
92 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
93 FlattenableUtils::write(buffer, size, value);
94 return NO_ERROR;
95 }
96 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
97 FlattenableUtils::read(buffer, size, value);
98 return NO_ERROR;
99 }
100
101 int32_t value = 0;
102};
103
Dan Stozad630e522016-12-01 15:16:31 -0800104struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
105 TestLightFlattenable() = default;
106 explicit TestLightFlattenable(int32_t v) : value(v) {}
107 int32_t value = 0;
108};
109
Dan Stoza6dd325b2017-04-07 14:31:51 -0700110// It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
111// but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
112// base class
113class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
114 public LightRefBase<TestLightRefBaseFlattenable> {
115public:
116 TestLightRefBaseFlattenable() = default;
117 explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
118
119 // Flattenable protocol
120 size_t getFlattenedSize() const { return sizeof(value); }
121 size_t getFdCount() const { return 0; }
122 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
123 FlattenableUtils::write(buffer, size, value);
124 return NO_ERROR;
125 }
126 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
127 FlattenableUtils::read(buffer, size, value);
128 return NO_ERROR;
129 }
130
131 int32_t value = 0;
132};
133
Dan Stoza1af8a882017-04-10 13:28:54 -0700134class TestParcelable : public Parcelable {
135public:
136 TestParcelable() = default;
137 explicit TestParcelable(int32_t value) : mValue(value) {}
138 TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
139 TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
140
141 // Parcelable interface
142 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
143 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
144
145 int32_t getValue() const { return mValue; }
146 void setValue(int32_t value) { mValue = value; }
147
148private:
149 int32_t mValue = 0;
150};
151
Dan Stozad630e522016-12-01 15:16:31 -0800152class ExitOnDeath : public IBinder::DeathRecipient {
153public:
154 ~ExitOnDeath() override = default;
155
156 void binderDied(const wp<IBinder>& /*who*/) override {
157 ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
158 exit(0);
159 }
160};
161
162// This callback class is used to test both one-way transactions and that sp<IInterface> can be
163// passed correctly
164class ICallback : public IInterface {
165public:
166 DECLARE_META_INTERFACE(Callback)
167
168 enum class Tag : uint32_t {
169 OnCallback = IBinder::FIRST_CALL_TRANSACTION,
170 Last,
171 };
172
173 virtual void onCallback(int32_t aPlusOne) = 0;
174};
175
176class BpCallback : public SafeBpInterface<ICallback> {
177public:
178 explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
179
180 void onCallback(int32_t aPlusOne) override {
181 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
182 return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
183 }
184
185private:
186 static constexpr const char* getLogTag() { return "BpCallback"; }
187};
188
189#pragma clang diagnostic push
190#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900191IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback")
Dan Stozad630e522016-12-01 15:16:31 -0800192#pragma clang diagnostic pop
193
194class BnCallback : public SafeBnInterface<ICallback> {
195public:
196 BnCallback() : SafeBnInterface("BnCallback") {}
197
198 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
199 uint32_t /*flags*/) override {
200 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
201 EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
202 ICallback::Tag tag = static_cast<ICallback::Tag>(code);
203 switch (tag) {
204 case ICallback::Tag::OnCallback: {
205 return callLocalAsync(data, reply, &ICallback::onCallback);
206 }
207 case ICallback::Tag::Last:
208 // Should not be possible because of the asserts at the beginning of the method
209 [&]() { FAIL(); }();
210 return UNKNOWN_ERROR;
211 }
212 }
213};
214
215class ISafeInterfaceTest : public IInterface {
216public:
217 DECLARE_META_INTERFACE(SafeInterfaceTest)
218
219 enum class Tag : uint32_t {
220 SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
221 ReturnsNoMemory,
222 LogicalNot,
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700223 ModifyEnum,
Dan Stozadf614ae2017-03-28 17:02:05 -0700224 IncrementFlattenable,
Dan Stozad630e522016-12-01 15:16:31 -0800225 IncrementLightFlattenable,
Dan Stoza6dd325b2017-04-07 14:31:51 -0700226 IncrementLightRefBaseFlattenable,
Dan Stoza2537db72017-04-07 16:32:38 -0700227 IncrementNativeHandle,
Dan Stozad630e522016-12-01 15:16:31 -0800228 IncrementNoCopyNoMove,
Dan Stoza1af8a882017-04-10 13:28:54 -0700229 IncrementParcelableVector,
Elliott Hughesd7657972021-04-12 15:31:22 -0700230 DoubleString,
Dan Stozad630e522016-12-01 15:16:31 -0800231 CallMeBack,
232 IncrementInt32,
233 IncrementUint32,
Dan Stoza662a8992017-04-06 16:18:39 -0700234 IncrementInt64,
235 IncrementUint64,
Dan Stoza4c6d9732018-11-14 10:18:14 -0800236 IncrementFloat,
Dan Stozad630e522016-12-01 15:16:31 -0800237 IncrementTwo,
238 Last,
239 };
240
241 // This is primarily so that the remote service dies when the test does, but it also serves to
242 // test the handling of sp<IBinder> and non-const methods
243 virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
244
245 // This is the most basic test since it doesn't require parceling any arguments
246 virtual status_t returnsNoMemory() const = 0;
247
248 // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
249 virtual status_t logicalNot(bool a, bool* notA) const = 0;
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700250 virtual status_t modifyEnum(TestEnum a, TestEnum* b) const = 0;
Dan Stozadf614ae2017-03-28 17:02:05 -0700251 virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800252 virtual status_t increment(const TestLightFlattenable& a,
253 TestLightFlattenable* aPlusOne) const = 0;
Dan Stoza6dd325b2017-04-07 14:31:51 -0700254 virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
255 sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
Dan Stoza2537db72017-04-07 16:32:38 -0700256 virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800257 virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
Dan Stoza1af8a882017-04-10 13:28:54 -0700258 virtual status_t increment(const std::vector<TestParcelable>& a,
259 std::vector<TestParcelable>* aPlusOne) const = 0;
Elliott Hughesd7657972021-04-12 15:31:22 -0700260 virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800261 // As mentioned above, sp<IBinder> is already tested by setDeathToken
262 virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
263 virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
264 virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
Dan Stoza662a8992017-04-06 16:18:39 -0700265 virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
266 virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
Dan Stoza4c6d9732018-11-14 10:18:14 -0800267 virtual status_t increment(float a, float* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800268
269 // This tests that input/output parameter interleaving works correctly
270 virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
271 int32_t* bPlusOne) const = 0;
272};
273
274class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
275public:
276 explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
277 : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
278
279 status_t setDeathToken(const sp<IBinder>& token) override {
280 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
281 return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
282 }
283 status_t returnsNoMemory() const override {
284 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
285 return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
286 }
287 status_t logicalNot(bool a, bool* notA) const override {
288 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
289 return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
290 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700291 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
292 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
293 return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b);
294 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700295 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
296 using Signature =
297 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
298 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
299 return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
300 }
Dan Stozad630e522016-12-01 15:16:31 -0800301 status_t increment(const TestLightFlattenable& a,
302 TestLightFlattenable* aPlusOne) const override {
303 using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
304 TestLightFlattenable*) const;
305 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
306 return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
307 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700308 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
309 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
310 using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
311 sp<TestLightRefBaseFlattenable>*) const;
312 return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
313 }
Dan Stoza2537db72017-04-07 16:32:38 -0700314 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
315 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
316 using Signature =
317 status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&, sp<NativeHandle>*) const;
318 return callRemote<Signature>(Tag::IncrementNativeHandle, a, aPlusOne);
319 }
Dan Stozad630e522016-12-01 15:16:31 -0800320 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
321 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
322 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
323 NoCopyNoMove* aPlusOne) const;
324 return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
325 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700326 status_t increment(const std::vector<TestParcelable>& a,
327 std::vector<TestParcelable>* aPlusOne) const override {
328 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
329 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
330 std::vector<TestParcelable>*);
331 return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
332 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700333 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800334 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700335 return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
336 doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800337 }
338 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
339 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
340 return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
341 a);
342 }
343 status_t increment(int32_t a, int32_t* aPlusOne) const override {
344 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
345 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
346 return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
347 }
348 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
349 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
350 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
351 return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
352 }
Dan Stoza662a8992017-04-06 16:18:39 -0700353 status_t increment(int64_t a, int64_t* aPlusOne) const override {
354 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
355 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
356 return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
357 }
358 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
359 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
360 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
361 return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
362 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800363 status_t increment(float a, float* aPlusOne) const override {
364 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
365 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
366 return callRemote<Signature>(Tag::IncrementFloat, a, aPlusOne);
367 }
Dan Stozad630e522016-12-01 15:16:31 -0800368 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
369 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
370 using Signature =
371 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
372 return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
373 }
374
375private:
376 static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
377};
378
379#pragma clang diagnostic push
380#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900381IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest")
Dan Stozad630e522016-12-01 15:16:31 -0800382
383static sp<IBinder::DeathRecipient> getDeathRecipient() {
384 static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
385 return recipient;
386}
387#pragma clang diagnostic pop
388
389class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
390public:
391 BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
392
393 status_t setDeathToken(const sp<IBinder>& token) override {
394 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
395 token->linkToDeath(getDeathRecipient());
396 return NO_ERROR;
397 }
398 status_t returnsNoMemory() const override {
399 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
400 return NO_MEMORY;
401 }
402 status_t logicalNot(bool a, bool* notA) const override {
403 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
404 *notA = !a;
405 return NO_ERROR;
406 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700407 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
408 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
409 *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID;
410 return NO_ERROR;
411 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700412 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
413 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
414 aPlusOne->value = a.value + 1;
415 return NO_ERROR;
416 }
Dan Stozad630e522016-12-01 15:16:31 -0800417 status_t increment(const TestLightFlattenable& a,
418 TestLightFlattenable* aPlusOne) const override {
419 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
420 aPlusOne->value = a.value + 1;
421 return NO_ERROR;
422 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700423 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
424 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
425 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
426 *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
427 return NO_ERROR;
428 }
Dan Stoza2537db72017-04-07 16:32:38 -0700429 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
430 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
431 native_handle* rawHandle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
432 if (rawHandle == nullptr) return NO_MEMORY;
433
434 // Copy the fd over directly
435 rawHandle->data[0] = dup(a->handle()->data[0]);
436
437 // Increment the int
438 rawHandle->data[1] = a->handle()->data[1] + 1;
439
440 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
441 // the native_handle when it goes out of scope
442 *aPlusOne = NativeHandle::create(rawHandle, true);
443 return NO_ERROR;
444 }
Dan Stozad630e522016-12-01 15:16:31 -0800445 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
446 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
447 aPlusOne->setValue(a.getValue() + 1);
448 return NO_ERROR;
449 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700450 status_t increment(const std::vector<TestParcelable>& a,
451 std::vector<TestParcelable>* aPlusOne) const override {
452 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
453 aPlusOne->resize(a.size());
454 for (size_t i = 0; i < a.size(); ++i) {
455 (*aPlusOne)[i].setValue(a[i].getValue() + 1);
456 }
457 return NO_ERROR;
458 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700459 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800460 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700461 *doubleStr = str + str;
Dan Stozad630e522016-12-01 15:16:31 -0800462 return NO_ERROR;
463 }
464 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
465 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
466 callback->onCallback(a + 1);
467 }
468 status_t increment(int32_t a, int32_t* aPlusOne) const override {
469 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
470 *aPlusOne = a + 1;
471 return NO_ERROR;
472 }
473 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
474 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
475 *aPlusOne = a + 1;
476 return NO_ERROR;
477 }
Dan Stoza662a8992017-04-06 16:18:39 -0700478 status_t increment(int64_t a, int64_t* aPlusOne) const override {
479 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
480 *aPlusOne = a + 1;
481 return NO_ERROR;
482 }
483 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
484 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
485 *aPlusOne = a + 1;
486 return NO_ERROR;
487 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800488 status_t increment(float a, float* aPlusOne) const override {
489 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
490 *aPlusOne = a + 1.0f;
491 return NO_ERROR;
492 }
Dan Stozad630e522016-12-01 15:16:31 -0800493 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
494 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
495 *aPlusOne = a + 1;
496 *bPlusOne = b + 1;
497 return NO_ERROR;
498 }
499
500 // BnInterface
501 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
502 uint32_t /*flags*/) override {
503 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
504 EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
505 ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
506 switch (tag) {
507 case ISafeInterfaceTest::Tag::SetDeathToken: {
508 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
509 }
510 case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
511 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
512 }
513 case ISafeInterfaceTest::Tag::LogicalNot: {
514 return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
515 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700516 case ISafeInterfaceTest::Tag::ModifyEnum: {
517 return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum);
518 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700519 case ISafeInterfaceTest::Tag::IncrementFlattenable: {
520 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
521 TestFlattenable* aPlusOne) const;
522 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
523 }
Dan Stozad630e522016-12-01 15:16:31 -0800524 case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
525 using Signature =
526 status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
527 TestLightFlattenable* aPlusOne) const;
528 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
529 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700530 case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
531 using Signature =
532 status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
533 sp<TestLightRefBaseFlattenable>*) const;
534 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
535 }
Dan Stoza2537db72017-04-07 16:32:38 -0700536 case ISafeInterfaceTest::Tag::IncrementNativeHandle: {
537 using Signature = status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&,
538 sp<NativeHandle>*) const;
539 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
540 }
Dan Stozad630e522016-12-01 15:16:31 -0800541 case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
542 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
543 NoCopyNoMove* aPlusOne) const;
544 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
545 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700546 case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
547 using Signature =
548 status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
549 std::vector<TestParcelable>*) const;
550 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
551 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700552 case ISafeInterfaceTest::Tag::DoubleString: {
553 return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
Dan Stozad630e522016-12-01 15:16:31 -0800554 }
555 case ISafeInterfaceTest::Tag::CallMeBack: {
556 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
557 }
558 case ISafeInterfaceTest::Tag::IncrementInt32: {
559 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
560 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
561 }
562 case ISafeInterfaceTest::Tag::IncrementUint32: {
563 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
564 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
565 }
Dan Stoza662a8992017-04-06 16:18:39 -0700566 case ISafeInterfaceTest::Tag::IncrementInt64: {
567 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
568 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
569 }
570 case ISafeInterfaceTest::Tag::IncrementUint64: {
571 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
572 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
573 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800574 case ISafeInterfaceTest::Tag::IncrementFloat: {
575 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
576 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
577 }
Dan Stozad630e522016-12-01 15:16:31 -0800578 case ISafeInterfaceTest::Tag::IncrementTwo: {
579 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
580 int32_t*) const;
581 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
582 }
583 case ISafeInterfaceTest::Tag::Last:
584 // Should not be possible because of the asserts at the beginning of the method
585 [&]() { FAIL(); }();
586 return UNKNOWN_ERROR;
587 }
588 }
589
590private:
591 static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
592};
593
594class SafeInterfaceTest : public ::testing::Test {
595public:
596 SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
597 ProcessState::self()->startThreadPool();
598 }
599 ~SafeInterfaceTest() override = default;
600
601protected:
602 sp<ISafeInterfaceTest> mSafeInterfaceTest;
603
604private:
605 static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
606
607 sp<ISafeInterfaceTest> getRemoteService() {
Steven Morelandcde5d532020-12-02 23:34:15 +0000608 sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
609 sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
610 EXPECT_TRUE(iface != nullptr);
Dan Stozad630e522016-12-01 15:16:31 -0800611
Steven Morelandcde5d532020-12-02 23:34:15 +0000612 iface->setDeathToken(new BBinder);
Dan Stozad630e522016-12-01 15:16:31 -0800613
Steven Morelandcde5d532020-12-02 23:34:15 +0000614 return iface;
Dan Stozad630e522016-12-01 15:16:31 -0800615 }
616};
617
618TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
619 status_t result = mSafeInterfaceTest->returnsNoMemory();
620 ASSERT_EQ(NO_MEMORY, result);
621}
622
623TEST_F(SafeInterfaceTest, TestLogicalNot) {
624 const bool a = true;
625 bool notA = true;
626 status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
627 ASSERT_EQ(NO_ERROR, result);
628 ASSERT_EQ(!a, notA);
629 // Test both since we don't want to accidentally catch a default false somewhere
630 const bool b = false;
631 bool notB = false;
632 result = mSafeInterfaceTest->logicalNot(b, &notB);
633 ASSERT_EQ(NO_ERROR, result);
634 ASSERT_EQ(!b, notB);
635}
636
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700637TEST_F(SafeInterfaceTest, TestModifyEnum) {
638 const TestEnum a = TestEnum::INITIAL;
639 TestEnum b = TestEnum::INVALID;
640 status_t result = mSafeInterfaceTest->modifyEnum(a, &b);
641 ASSERT_EQ(NO_ERROR, result);
642 ASSERT_EQ(TestEnum::FINAL, b);
643}
644
Dan Stozadf614ae2017-03-28 17:02:05 -0700645TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
646 const TestFlattenable a{1};
647 TestFlattenable aPlusOne{0};
648 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
649 ASSERT_EQ(NO_ERROR, result);
650 ASSERT_EQ(a.value + 1, aPlusOne.value);
651}
652
Dan Stozad630e522016-12-01 15:16:31 -0800653TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
654 const TestLightFlattenable a{1};
655 TestLightFlattenable aPlusOne{0};
656 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
657 ASSERT_EQ(NO_ERROR, result);
658 ASSERT_EQ(a.value + 1, aPlusOne.value);
659}
660
Dan Stoza6dd325b2017-04-07 14:31:51 -0700661TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
662 sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
663 sp<TestLightRefBaseFlattenable> aPlusOne;
664 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
665 ASSERT_EQ(NO_ERROR, result);
666 ASSERT_NE(nullptr, aPlusOne.get());
667 ASSERT_EQ(a->value + 1, aPlusOne->value);
668}
669
Dan Stoza2537db72017-04-07 16:32:38 -0700670namespace { // Anonymous namespace
671
672bool fdsAreEquivalent(int a, int b) {
673 struct stat statA {};
674 struct stat statB {};
675 if (fstat(a, &statA) != 0) return false;
676 if (fstat(b, &statB) != 0) return false;
677 return (statA.st_dev == statB.st_dev) && (statA.st_ino == statB.st_ino);
678}
679
680} // Anonymous namespace
681
682TEST_F(SafeInterfaceTest, TestIncrementNativeHandle) {
683 // Create an fd we can use to send and receive from the remote process
684 base::unique_fd eventFd{eventfd(0 /*initval*/, 0 /*flags*/)};
685 ASSERT_NE(-1, eventFd);
686
687 // Determine the maximum number of fds this process can have open
688 struct rlimit limit {};
689 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &limit));
Steven Moreland56044032023-05-24 19:31:25 +0000690 uint64_t maxFds = limit.rlim_cur;
691
692 ALOG(LOG_INFO, "SafeInterfaceTest", "%s max FDs: %" PRIu64, __PRETTY_FUNCTION__, maxFds);
Dan Stoza2537db72017-04-07 16:32:38 -0700693
694 // Perform this test enough times to rule out fd leaks
Steven Moreland56044032023-05-24 19:31:25 +0000695 for (uint32_t iter = 0; iter < (maxFds + 100); ++iter) {
Dan Stoza2537db72017-04-07 16:32:38 -0700696 native_handle* handle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
697 ASSERT_NE(nullptr, handle);
698 handle->data[0] = dup(eventFd.get());
699 handle->data[1] = 1;
700
701 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
702 // the native_handle when it goes out of scope
703 sp<NativeHandle> a = NativeHandle::create(handle, true);
704
705 sp<NativeHandle> aPlusOne;
706 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
707 ASSERT_EQ(NO_ERROR, result);
708 ASSERT_TRUE(fdsAreEquivalent(a->handle()->data[0], aPlusOne->handle()->data[0]));
709 ASSERT_EQ(a->handle()->data[1] + 1, aPlusOne->handle()->data[1]);
710 }
711}
712
Dan Stozad630e522016-12-01 15:16:31 -0800713TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
714 const NoCopyNoMove a{1};
715 NoCopyNoMove aPlusOne{0};
716 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
717 ASSERT_EQ(NO_ERROR, result);
718 ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
719}
720
Dan Stoza1af8a882017-04-10 13:28:54 -0700721TEST_F(SafeInterfaceTest, TestIncremementParcelableVector) {
722 const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
723 std::vector<TestParcelable> aPlusOne;
724 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
Steven Moreland573adc12019-07-17 13:29:06 -0700725 ASSERT_EQ(NO_ERROR, result);
Dan Stoza1af8a882017-04-10 13:28:54 -0700726 ASSERT_EQ(a.size(), aPlusOne.size());
727 for (size_t i = 0; i < a.size(); ++i) {
728 ASSERT_EQ(a[i].getValue() + 1, aPlusOne[i].getValue());
729 }
730}
731
Elliott Hughesd7657972021-04-12 15:31:22 -0700732TEST_F(SafeInterfaceTest, TestDoubleString) {
733 const String8 str{"asdf"};
734 String8 doubleStr;
735 status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800736 ASSERT_EQ(NO_ERROR, result);
Elliott Hughesd7657972021-04-12 15:31:22 -0700737 ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
Dan Stozad630e522016-12-01 15:16:31 -0800738}
739
740TEST_F(SafeInterfaceTest, TestCallMeBack) {
741 class CallbackReceiver : public BnCallback {
742 public:
743 void onCallback(int32_t aPlusOne) override {
744 ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
745 std::unique_lock<decltype(mMutex)> lock(mMutex);
746 mValue = aPlusOne;
747 mCondition.notify_one();
748 }
749
750 std::optional<int32_t> waitForCallback() {
751 std::unique_lock<decltype(mMutex)> lock(mMutex);
752 bool success =
753 mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
754 return success ? mValue : std::nullopt;
755 }
756
757 private:
758 std::mutex mMutex;
759 std::condition_variable mCondition;
760 std::optional<int32_t> mValue;
761 };
762
763 sp<CallbackReceiver> receiver = new CallbackReceiver;
764 const int32_t a = 1;
765 mSafeInterfaceTest->callMeBack(receiver, a);
766 auto result = receiver->waitForCallback();
767 ASSERT_TRUE(result);
768 ASSERT_EQ(a + 1, *result);
769}
770
771TEST_F(SafeInterfaceTest, TestIncrementInt32) {
772 const int32_t a = 1;
773 int32_t aPlusOne = 0;
774 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
775 ASSERT_EQ(NO_ERROR, result);
776 ASSERT_EQ(a + 1, aPlusOne);
777}
778
779TEST_F(SafeInterfaceTest, TestIncrementUint32) {
780 const uint32_t a = 1;
781 uint32_t aPlusOne = 0;
782 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
783 ASSERT_EQ(NO_ERROR, result);
784 ASSERT_EQ(a + 1, aPlusOne);
785}
786
Dan Stoza662a8992017-04-06 16:18:39 -0700787TEST_F(SafeInterfaceTest, TestIncrementInt64) {
788 const int64_t a = 1;
789 int64_t aPlusOne = 0;
790 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
791 ASSERT_EQ(NO_ERROR, result);
792 ASSERT_EQ(a + 1, aPlusOne);
793}
794
795TEST_F(SafeInterfaceTest, TestIncrementUint64) {
796 const uint64_t a = 1;
797 uint64_t aPlusOne = 0;
798 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
799 ASSERT_EQ(NO_ERROR, result);
800 ASSERT_EQ(a + 1, aPlusOne);
801}
802
Dan Stoza4c6d9732018-11-14 10:18:14 -0800803TEST_F(SafeInterfaceTest, TestIncrementFloat) {
804 const float a = 1.0f;
805 float aPlusOne = 0.0f;
806 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
807 ASSERT_EQ(NO_ERROR, result);
808 ASSERT_EQ(a + 1.0f, aPlusOne);
809}
810
Dan Stozad630e522016-12-01 15:16:31 -0800811TEST_F(SafeInterfaceTest, TestIncrementTwo) {
812 const int32_t a = 1;
813 int32_t aPlusOne = 0;
814 const int32_t b = 2;
815 int32_t bPlusOne = 0;
816 status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
817 ASSERT_EQ(NO_ERROR, result);
818 ASSERT_EQ(a + 1, aPlusOne);
819 ASSERT_EQ(b + 1, bPlusOne);
820}
821
Steven Morelandcde5d532020-12-02 23:34:15 +0000822extern "C" int main(int argc, char **argv) {
823 testing::InitGoogleTest(&argc, argv);
824
825 if (fork() == 0) {
826 prctl(PR_SET_PDEATHSIG, SIGHUP);
827 sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
828 status_t status = defaultServiceManager()->addService(kServiceName, nativeService);
829 if (status != OK) {
830 ALOG(LOG_INFO, "SafeInterfaceServer", "could not register");
831 return EXIT_FAILURE;
832 }
833 IPCThreadState::self()->joinThreadPool();
834 return EXIT_FAILURE;
835 }
836
837 return RUN_ALL_TESTS();
838}
839
Dan Stozad630e522016-12-01 15:16:31 -0800840} // namespace tests
841} // namespace android