blob: cbbbe74bb50ed3680d606028786235809c94f010 [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
Dan Stozad630e522016-12-01 15:16:31 -080043using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
44
45namespace android {
46namespace tests {
47
Steven Morelandcde5d532020-12-02 23:34:15 +000048static const String16 kServiceName("SafeInterfaceTest");
49
Dan Stoza81ea3ef2017-04-07 15:00:18 -070050enum class TestEnum : uint32_t {
51 INVALID = 0,
52 INITIAL = 1,
53 FINAL = 2,
54};
55
Dan Stozad630e522016-12-01 15:16:31 -080056// This class serves two purposes:
57// 1) It ensures that the implementation doesn't require copying or moving the data (for
58// efficiency purposes)
59// 2) It tests that Parcelables can be passed correctly
60class NoCopyNoMove : public Parcelable {
61public:
62 NoCopyNoMove() = default;
63 explicit NoCopyNoMove(int32_t value) : mValue(value) {}
64 ~NoCopyNoMove() override = default;
65
66 // Not copyable
67 NoCopyNoMove(const NoCopyNoMove&) = delete;
68 NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
69
70 // Not movable
71 NoCopyNoMove(NoCopyNoMove&&) = delete;
72 NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
73
74 // Parcelable interface
75 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
76 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
77
78 int32_t getValue() const { return mValue; }
79 void setValue(int32_t value) { mValue = value; }
80
81private:
82 int32_t mValue = 0;
Steven Moreland573adc12019-07-17 13:29:06 -070083 __attribute__((unused)) uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
Dan Stozad630e522016-12-01 15:16:31 -080084};
85
Dan Stozadf614ae2017-03-28 17:02:05 -070086struct TestFlattenable : Flattenable<TestFlattenable> {
87 TestFlattenable() = default;
88 explicit TestFlattenable(int32_t v) : value(v) {}
89
90 // Flattenable protocol
91 size_t getFlattenedSize() const { return sizeof(value); }
92 size_t getFdCount() const { return 0; }
93 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
94 FlattenableUtils::write(buffer, size, value);
95 return NO_ERROR;
96 }
97 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
98 FlattenableUtils::read(buffer, size, value);
99 return NO_ERROR;
100 }
101
102 int32_t value = 0;
103};
104
Dan Stozad630e522016-12-01 15:16:31 -0800105struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
106 TestLightFlattenable() = default;
107 explicit TestLightFlattenable(int32_t v) : value(v) {}
108 int32_t value = 0;
109};
110
Dan Stoza6dd325b2017-04-07 14:31:51 -0700111// It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
112// but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
113// base class
114class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
115 public LightRefBase<TestLightRefBaseFlattenable> {
116public:
117 TestLightRefBaseFlattenable() = default;
118 explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
119
120 // Flattenable protocol
121 size_t getFlattenedSize() const { return sizeof(value); }
122 size_t getFdCount() const { return 0; }
123 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
124 FlattenableUtils::write(buffer, size, value);
125 return NO_ERROR;
126 }
127 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
128 FlattenableUtils::read(buffer, size, value);
129 return NO_ERROR;
130 }
131
132 int32_t value = 0;
133};
134
Dan Stoza1af8a882017-04-10 13:28:54 -0700135class TestParcelable : public Parcelable {
136public:
137 TestParcelable() = default;
138 explicit TestParcelable(int32_t value) : mValue(value) {}
139 TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
140 TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
141
142 // Parcelable interface
143 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
144 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
145
146 int32_t getValue() const { return mValue; }
147 void setValue(int32_t value) { mValue = value; }
148
149private:
150 int32_t mValue = 0;
151};
152
Dan Stozad630e522016-12-01 15:16:31 -0800153class ExitOnDeath : public IBinder::DeathRecipient {
154public:
155 ~ExitOnDeath() override = default;
156
157 void binderDied(const wp<IBinder>& /*who*/) override {
158 ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
159 exit(0);
160 }
161};
162
163// This callback class is used to test both one-way transactions and that sp<IInterface> can be
164// passed correctly
165class ICallback : public IInterface {
166public:
167 DECLARE_META_INTERFACE(Callback)
168
169 enum class Tag : uint32_t {
170 OnCallback = IBinder::FIRST_CALL_TRANSACTION,
171 Last,
172 };
173
174 virtual void onCallback(int32_t aPlusOne) = 0;
175};
176
177class BpCallback : public SafeBpInterface<ICallback> {
178public:
179 explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
180
181 void onCallback(int32_t aPlusOne) override {
182 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
183 return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
184 }
185
186private:
187 static constexpr const char* getLogTag() { return "BpCallback"; }
188};
189
190#pragma clang diagnostic push
191#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900192IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback")
Dan Stozad630e522016-12-01 15:16:31 -0800193#pragma clang diagnostic pop
194
195class BnCallback : public SafeBnInterface<ICallback> {
196public:
197 BnCallback() : SafeBnInterface("BnCallback") {}
198
199 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
200 uint32_t /*flags*/) override {
201 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
202 EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
203 ICallback::Tag tag = static_cast<ICallback::Tag>(code);
204 switch (tag) {
205 case ICallback::Tag::OnCallback: {
206 return callLocalAsync(data, reply, &ICallback::onCallback);
207 }
208 case ICallback::Tag::Last:
209 // Should not be possible because of the asserts at the beginning of the method
210 [&]() { FAIL(); }();
211 return UNKNOWN_ERROR;
212 }
213 }
214};
215
216class ISafeInterfaceTest : public IInterface {
217public:
218 DECLARE_META_INTERFACE(SafeInterfaceTest)
219
220 enum class Tag : uint32_t {
221 SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
222 ReturnsNoMemory,
223 LogicalNot,
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700224 ModifyEnum,
Dan Stozadf614ae2017-03-28 17:02:05 -0700225 IncrementFlattenable,
Dan Stozad630e522016-12-01 15:16:31 -0800226 IncrementLightFlattenable,
Dan Stoza6dd325b2017-04-07 14:31:51 -0700227 IncrementLightRefBaseFlattenable,
Dan Stoza2537db72017-04-07 16:32:38 -0700228 IncrementNativeHandle,
Dan Stozad630e522016-12-01 15:16:31 -0800229 IncrementNoCopyNoMove,
Dan Stoza1af8a882017-04-10 13:28:54 -0700230 IncrementParcelableVector,
Elliott Hughesd7657972021-04-12 15:31:22 -0700231 DoubleString,
Dan Stozad630e522016-12-01 15:16:31 -0800232 CallMeBack,
233 IncrementInt32,
234 IncrementUint32,
Dan Stoza662a8992017-04-06 16:18:39 -0700235 IncrementInt64,
236 IncrementUint64,
Dan Stoza4c6d9732018-11-14 10:18:14 -0800237 IncrementFloat,
Dan Stozad630e522016-12-01 15:16:31 -0800238 IncrementTwo,
239 Last,
240 };
241
242 // This is primarily so that the remote service dies when the test does, but it also serves to
243 // test the handling of sp<IBinder> and non-const methods
244 virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
245
246 // This is the most basic test since it doesn't require parceling any arguments
247 virtual status_t returnsNoMemory() const = 0;
248
249 // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
250 virtual status_t logicalNot(bool a, bool* notA) const = 0;
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700251 virtual status_t modifyEnum(TestEnum a, TestEnum* b) const = 0;
Dan Stozadf614ae2017-03-28 17:02:05 -0700252 virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800253 virtual status_t increment(const TestLightFlattenable& a,
254 TestLightFlattenable* aPlusOne) const = 0;
Dan Stoza6dd325b2017-04-07 14:31:51 -0700255 virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
256 sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
Dan Stoza2537db72017-04-07 16:32:38 -0700257 virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800258 virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
Dan Stoza1af8a882017-04-10 13:28:54 -0700259 virtual status_t increment(const std::vector<TestParcelable>& a,
260 std::vector<TestParcelable>* aPlusOne) const = 0;
Elliott Hughesd7657972021-04-12 15:31:22 -0700261 virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800262 // As mentioned above, sp<IBinder> is already tested by setDeathToken
263 virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
264 virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
265 virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
Dan Stoza662a8992017-04-06 16:18:39 -0700266 virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
267 virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
Dan Stoza4c6d9732018-11-14 10:18:14 -0800268 virtual status_t increment(float a, float* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800269
270 // This tests that input/output parameter interleaving works correctly
271 virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
272 int32_t* bPlusOne) const = 0;
273};
274
275class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
276public:
277 explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
278 : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
279
280 status_t setDeathToken(const sp<IBinder>& token) override {
281 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
282 return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
283 }
284 status_t returnsNoMemory() const override {
285 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
286 return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
287 }
288 status_t logicalNot(bool a, bool* notA) const override {
289 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
290 return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
291 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700292 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
293 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
294 return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b);
295 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700296 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
297 using Signature =
298 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
299 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
300 return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
301 }
Dan Stozad630e522016-12-01 15:16:31 -0800302 status_t increment(const TestLightFlattenable& a,
303 TestLightFlattenable* aPlusOne) const override {
304 using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
305 TestLightFlattenable*) const;
306 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
307 return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
308 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700309 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
310 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
311 using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
312 sp<TestLightRefBaseFlattenable>*) const;
313 return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
314 }
Dan Stoza2537db72017-04-07 16:32:38 -0700315 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
316 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
317 using Signature =
318 status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&, sp<NativeHandle>*) const;
319 return callRemote<Signature>(Tag::IncrementNativeHandle, a, aPlusOne);
320 }
Dan Stozad630e522016-12-01 15:16:31 -0800321 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
322 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
323 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
324 NoCopyNoMove* aPlusOne) const;
325 return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
326 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700327 status_t increment(const std::vector<TestParcelable>& a,
328 std::vector<TestParcelable>* aPlusOne) const override {
329 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
330 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
331 std::vector<TestParcelable>*);
332 return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
333 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700334 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800335 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700336 return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
337 doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800338 }
339 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
340 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
341 return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
342 a);
343 }
344 status_t increment(int32_t a, int32_t* aPlusOne) const override {
345 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
346 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
347 return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
348 }
349 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
350 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
351 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
352 return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
353 }
Dan Stoza662a8992017-04-06 16:18:39 -0700354 status_t increment(int64_t a, int64_t* aPlusOne) const override {
355 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
356 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
357 return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
358 }
359 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
360 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
361 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
362 return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
363 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800364 status_t increment(float a, float* aPlusOne) const override {
365 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
366 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
367 return callRemote<Signature>(Tag::IncrementFloat, a, aPlusOne);
368 }
Dan Stozad630e522016-12-01 15:16:31 -0800369 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
370 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
371 using Signature =
372 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
373 return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
374 }
375
376private:
377 static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
378};
379
380#pragma clang diagnostic push
381#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900382IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest")
Dan Stozad630e522016-12-01 15:16:31 -0800383
384static sp<IBinder::DeathRecipient> getDeathRecipient() {
385 static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
386 return recipient;
387}
388#pragma clang diagnostic pop
389
390class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
391public:
392 BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
393
394 status_t setDeathToken(const sp<IBinder>& token) override {
395 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
396 token->linkToDeath(getDeathRecipient());
397 return NO_ERROR;
398 }
399 status_t returnsNoMemory() const override {
400 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
401 return NO_MEMORY;
402 }
403 status_t logicalNot(bool a, bool* notA) const override {
404 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
405 *notA = !a;
406 return NO_ERROR;
407 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700408 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
409 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
410 *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID;
411 return NO_ERROR;
412 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700413 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
414 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
415 aPlusOne->value = a.value + 1;
416 return NO_ERROR;
417 }
Dan Stozad630e522016-12-01 15:16:31 -0800418 status_t increment(const TestLightFlattenable& a,
419 TestLightFlattenable* aPlusOne) const override {
420 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
421 aPlusOne->value = a.value + 1;
422 return NO_ERROR;
423 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700424 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
425 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
426 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
427 *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
428 return NO_ERROR;
429 }
Dan Stoza2537db72017-04-07 16:32:38 -0700430 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
431 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
432 native_handle* rawHandle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
433 if (rawHandle == nullptr) return NO_MEMORY;
434
435 // Copy the fd over directly
436 rawHandle->data[0] = dup(a->handle()->data[0]);
437
438 // Increment the int
439 rawHandle->data[1] = a->handle()->data[1] + 1;
440
441 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
442 // the native_handle when it goes out of scope
443 *aPlusOne = NativeHandle::create(rawHandle, true);
444 return NO_ERROR;
445 }
Dan Stozad630e522016-12-01 15:16:31 -0800446 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
447 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
448 aPlusOne->setValue(a.getValue() + 1);
449 return NO_ERROR;
450 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700451 status_t increment(const std::vector<TestParcelable>& a,
452 std::vector<TestParcelable>* aPlusOne) const override {
453 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
454 aPlusOne->resize(a.size());
455 for (size_t i = 0; i < a.size(); ++i) {
456 (*aPlusOne)[i].setValue(a[i].getValue() + 1);
457 }
458 return NO_ERROR;
459 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700460 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800461 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700462 *doubleStr = str + str;
Dan Stozad630e522016-12-01 15:16:31 -0800463 return NO_ERROR;
464 }
465 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
466 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
467 callback->onCallback(a + 1);
468 }
469 status_t increment(int32_t a, int32_t* aPlusOne) const override {
470 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
471 *aPlusOne = a + 1;
472 return NO_ERROR;
473 }
474 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
475 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
476 *aPlusOne = a + 1;
477 return NO_ERROR;
478 }
Dan Stoza662a8992017-04-06 16:18:39 -0700479 status_t increment(int64_t a, int64_t* aPlusOne) const override {
480 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
481 *aPlusOne = a + 1;
482 return NO_ERROR;
483 }
484 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
485 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
486 *aPlusOne = a + 1;
487 return NO_ERROR;
488 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800489 status_t increment(float a, float* aPlusOne) const override {
490 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
491 *aPlusOne = a + 1.0f;
492 return NO_ERROR;
493 }
Dan Stozad630e522016-12-01 15:16:31 -0800494 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
495 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
496 *aPlusOne = a + 1;
497 *bPlusOne = b + 1;
498 return NO_ERROR;
499 }
500
501 // BnInterface
502 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
503 uint32_t /*flags*/) override {
504 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
505 EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
506 ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
507 switch (tag) {
508 case ISafeInterfaceTest::Tag::SetDeathToken: {
509 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
510 }
511 case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
512 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
513 }
514 case ISafeInterfaceTest::Tag::LogicalNot: {
515 return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
516 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700517 case ISafeInterfaceTest::Tag::ModifyEnum: {
518 return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum);
519 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700520 case ISafeInterfaceTest::Tag::IncrementFlattenable: {
521 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
522 TestFlattenable* aPlusOne) const;
523 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
524 }
Dan Stozad630e522016-12-01 15:16:31 -0800525 case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
526 using Signature =
527 status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
528 TestLightFlattenable* aPlusOne) const;
529 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
530 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700531 case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
532 using Signature =
533 status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
534 sp<TestLightRefBaseFlattenable>*) const;
535 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
536 }
Dan Stoza2537db72017-04-07 16:32:38 -0700537 case ISafeInterfaceTest::Tag::IncrementNativeHandle: {
538 using Signature = status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&,
539 sp<NativeHandle>*) const;
540 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
541 }
Dan Stozad630e522016-12-01 15:16:31 -0800542 case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
543 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
544 NoCopyNoMove* aPlusOne) const;
545 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
546 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700547 case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
548 using Signature =
549 status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
550 std::vector<TestParcelable>*) const;
551 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
552 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700553 case ISafeInterfaceTest::Tag::DoubleString: {
554 return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
Dan Stozad630e522016-12-01 15:16:31 -0800555 }
556 case ISafeInterfaceTest::Tag::CallMeBack: {
557 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
558 }
559 case ISafeInterfaceTest::Tag::IncrementInt32: {
560 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
561 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
562 }
563 case ISafeInterfaceTest::Tag::IncrementUint32: {
564 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
565 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
566 }
Dan Stoza662a8992017-04-06 16:18:39 -0700567 case ISafeInterfaceTest::Tag::IncrementInt64: {
568 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
569 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
570 }
571 case ISafeInterfaceTest::Tag::IncrementUint64: {
572 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
573 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
574 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800575 case ISafeInterfaceTest::Tag::IncrementFloat: {
576 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
577 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
578 }
Dan Stozad630e522016-12-01 15:16:31 -0800579 case ISafeInterfaceTest::Tag::IncrementTwo: {
580 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
581 int32_t*) const;
582 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
583 }
584 case ISafeInterfaceTest::Tag::Last:
585 // Should not be possible because of the asserts at the beginning of the method
586 [&]() { FAIL(); }();
587 return UNKNOWN_ERROR;
588 }
589 }
590
591private:
592 static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
593};
594
595class SafeInterfaceTest : public ::testing::Test {
596public:
597 SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
598 ProcessState::self()->startThreadPool();
599 }
600 ~SafeInterfaceTest() override = default;
601
602protected:
603 sp<ISafeInterfaceTest> mSafeInterfaceTest;
604
605private:
606 static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
607
608 sp<ISafeInterfaceTest> getRemoteService() {
Tomasz Wasilczykbb07b982023-10-11 21:25:36 +0000609#pragma clang diagnostic push
610#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Steven Morelandcde5d532020-12-02 23:34:15 +0000611 sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
Tomasz Wasilczykbb07b982023-10-11 21:25:36 +0000612#pragma clang diagnostic pop
Steven Morelandcde5d532020-12-02 23:34:15 +0000613 sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
614 EXPECT_TRUE(iface != nullptr);
Dan Stozad630e522016-12-01 15:16:31 -0800615
Steven Morelandcde5d532020-12-02 23:34:15 +0000616 iface->setDeathToken(new BBinder);
Dan Stozad630e522016-12-01 15:16:31 -0800617
Steven Morelandcde5d532020-12-02 23:34:15 +0000618 return iface;
Dan Stozad630e522016-12-01 15:16:31 -0800619 }
620};
621
622TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
623 status_t result = mSafeInterfaceTest->returnsNoMemory();
624 ASSERT_EQ(NO_MEMORY, result);
625}
626
627TEST_F(SafeInterfaceTest, TestLogicalNot) {
628 const bool a = true;
629 bool notA = true;
630 status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
631 ASSERT_EQ(NO_ERROR, result);
632 ASSERT_EQ(!a, notA);
633 // Test both since we don't want to accidentally catch a default false somewhere
634 const bool b = false;
635 bool notB = false;
636 result = mSafeInterfaceTest->logicalNot(b, &notB);
637 ASSERT_EQ(NO_ERROR, result);
638 ASSERT_EQ(!b, notB);
639}
640
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700641TEST_F(SafeInterfaceTest, TestModifyEnum) {
642 const TestEnum a = TestEnum::INITIAL;
643 TestEnum b = TestEnum::INVALID;
644 status_t result = mSafeInterfaceTest->modifyEnum(a, &b);
645 ASSERT_EQ(NO_ERROR, result);
646 ASSERT_EQ(TestEnum::FINAL, b);
647}
648
Dan Stozadf614ae2017-03-28 17:02:05 -0700649TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
650 const TestFlattenable a{1};
651 TestFlattenable aPlusOne{0};
652 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
653 ASSERT_EQ(NO_ERROR, result);
654 ASSERT_EQ(a.value + 1, aPlusOne.value);
655}
656
Dan Stozad630e522016-12-01 15:16:31 -0800657TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
658 const TestLightFlattenable a{1};
659 TestLightFlattenable aPlusOne{0};
660 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
661 ASSERT_EQ(NO_ERROR, result);
662 ASSERT_EQ(a.value + 1, aPlusOne.value);
663}
664
Dan Stoza6dd325b2017-04-07 14:31:51 -0700665TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
666 sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
667 sp<TestLightRefBaseFlattenable> aPlusOne;
668 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
669 ASSERT_EQ(NO_ERROR, result);
670 ASSERT_NE(nullptr, aPlusOne.get());
671 ASSERT_EQ(a->value + 1, aPlusOne->value);
672}
673
Dan Stoza2537db72017-04-07 16:32:38 -0700674namespace { // Anonymous namespace
675
676bool fdsAreEquivalent(int a, int b) {
677 struct stat statA {};
678 struct stat statB {};
679 if (fstat(a, &statA) != 0) return false;
680 if (fstat(b, &statB) != 0) return false;
681 return (statA.st_dev == statB.st_dev) && (statA.st_ino == statB.st_ino);
682}
683
684} // Anonymous namespace
685
686TEST_F(SafeInterfaceTest, TestIncrementNativeHandle) {
687 // Create an fd we can use to send and receive from the remote process
688 base::unique_fd eventFd{eventfd(0 /*initval*/, 0 /*flags*/)};
689 ASSERT_NE(-1, eventFd);
690
691 // Determine the maximum number of fds this process can have open
692 struct rlimit limit {};
693 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &limit));
Steven Moreland56044032023-05-24 19:31:25 +0000694 uint64_t maxFds = limit.rlim_cur;
695
696 ALOG(LOG_INFO, "SafeInterfaceTest", "%s max FDs: %" PRIu64, __PRETTY_FUNCTION__, maxFds);
Dan Stoza2537db72017-04-07 16:32:38 -0700697
698 // Perform this test enough times to rule out fd leaks
Steven Moreland56044032023-05-24 19:31:25 +0000699 for (uint32_t iter = 0; iter < (maxFds + 100); ++iter) {
Dan Stoza2537db72017-04-07 16:32:38 -0700700 native_handle* handle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
701 ASSERT_NE(nullptr, handle);
702 handle->data[0] = dup(eventFd.get());
703 handle->data[1] = 1;
704
705 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
706 // the native_handle when it goes out of scope
707 sp<NativeHandle> a = NativeHandle::create(handle, true);
708
709 sp<NativeHandle> aPlusOne;
710 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
711 ASSERT_EQ(NO_ERROR, result);
712 ASSERT_TRUE(fdsAreEquivalent(a->handle()->data[0], aPlusOne->handle()->data[0]));
713 ASSERT_EQ(a->handle()->data[1] + 1, aPlusOne->handle()->data[1]);
714 }
715}
716
Dan Stozad630e522016-12-01 15:16:31 -0800717TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
718 const NoCopyNoMove a{1};
719 NoCopyNoMove aPlusOne{0};
720 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
721 ASSERT_EQ(NO_ERROR, result);
722 ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
723}
724
Dan Stoza1af8a882017-04-10 13:28:54 -0700725TEST_F(SafeInterfaceTest, TestIncremementParcelableVector) {
726 const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
727 std::vector<TestParcelable> aPlusOne;
728 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
Steven Moreland573adc12019-07-17 13:29:06 -0700729 ASSERT_EQ(NO_ERROR, result);
Dan Stoza1af8a882017-04-10 13:28:54 -0700730 ASSERT_EQ(a.size(), aPlusOne.size());
731 for (size_t i = 0; i < a.size(); ++i) {
732 ASSERT_EQ(a[i].getValue() + 1, aPlusOne[i].getValue());
733 }
734}
735
Elliott Hughesd7657972021-04-12 15:31:22 -0700736TEST_F(SafeInterfaceTest, TestDoubleString) {
737 const String8 str{"asdf"};
738 String8 doubleStr;
739 status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800740 ASSERT_EQ(NO_ERROR, result);
Elliott Hughesd7657972021-04-12 15:31:22 -0700741 ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
Dan Stozad630e522016-12-01 15:16:31 -0800742}
743
744TEST_F(SafeInterfaceTest, TestCallMeBack) {
745 class CallbackReceiver : public BnCallback {
746 public:
747 void onCallback(int32_t aPlusOne) override {
748 ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
749 std::unique_lock<decltype(mMutex)> lock(mMutex);
750 mValue = aPlusOne;
751 mCondition.notify_one();
752 }
753
754 std::optional<int32_t> waitForCallback() {
755 std::unique_lock<decltype(mMutex)> lock(mMutex);
756 bool success =
757 mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
758 return success ? mValue : std::nullopt;
759 }
760
761 private:
762 std::mutex mMutex;
763 std::condition_variable mCondition;
764 std::optional<int32_t> mValue;
765 };
766
767 sp<CallbackReceiver> receiver = new CallbackReceiver;
768 const int32_t a = 1;
769 mSafeInterfaceTest->callMeBack(receiver, a);
770 auto result = receiver->waitForCallback();
771 ASSERT_TRUE(result);
772 ASSERT_EQ(a + 1, *result);
773}
774
775TEST_F(SafeInterfaceTest, TestIncrementInt32) {
776 const int32_t a = 1;
777 int32_t aPlusOne = 0;
778 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
779 ASSERT_EQ(NO_ERROR, result);
780 ASSERT_EQ(a + 1, aPlusOne);
781}
782
783TEST_F(SafeInterfaceTest, TestIncrementUint32) {
784 const uint32_t a = 1;
785 uint32_t aPlusOne = 0;
786 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
787 ASSERT_EQ(NO_ERROR, result);
788 ASSERT_EQ(a + 1, aPlusOne);
789}
790
Dan Stoza662a8992017-04-06 16:18:39 -0700791TEST_F(SafeInterfaceTest, TestIncrementInt64) {
792 const int64_t a = 1;
793 int64_t aPlusOne = 0;
794 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
795 ASSERT_EQ(NO_ERROR, result);
796 ASSERT_EQ(a + 1, aPlusOne);
797}
798
799TEST_F(SafeInterfaceTest, TestIncrementUint64) {
800 const uint64_t a = 1;
801 uint64_t aPlusOne = 0;
802 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
803 ASSERT_EQ(NO_ERROR, result);
804 ASSERT_EQ(a + 1, aPlusOne);
805}
806
Dan Stoza4c6d9732018-11-14 10:18:14 -0800807TEST_F(SafeInterfaceTest, TestIncrementFloat) {
808 const float a = 1.0f;
809 float aPlusOne = 0.0f;
810 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
811 ASSERT_EQ(NO_ERROR, result);
812 ASSERT_EQ(a + 1.0f, aPlusOne);
813}
814
Dan Stozad630e522016-12-01 15:16:31 -0800815TEST_F(SafeInterfaceTest, TestIncrementTwo) {
816 const int32_t a = 1;
817 int32_t aPlusOne = 0;
818 const int32_t b = 2;
819 int32_t bPlusOne = 0;
820 status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
821 ASSERT_EQ(NO_ERROR, result);
822 ASSERT_EQ(a + 1, aPlusOne);
823 ASSERT_EQ(b + 1, bPlusOne);
824}
825
Steven Morelandcde5d532020-12-02 23:34:15 +0000826extern "C" int main(int argc, char **argv) {
827 testing::InitGoogleTest(&argc, argv);
828
829 if (fork() == 0) {
830 prctl(PR_SET_PDEATHSIG, SIGHUP);
831 sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
832 status_t status = defaultServiceManager()->addService(kServiceName, nativeService);
833 if (status != OK) {
834 ALOG(LOG_INFO, "SafeInterfaceServer", "could not register");
835 return EXIT_FAILURE;
836 }
837 IPCThreadState::self()->joinThreadPool();
838 return EXIT_FAILURE;
839 }
840
841 return RUN_ALL_TESTS();
842}
843
Dan Stozad630e522016-12-01 15:16:31 -0800844} // namespace tests
845} // namespace android