blob: c857d62cb2ef8aaadb8af23ddd99c95de43f0567 [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
Dan Stoza2537db72017-04-07 16:32:38 -070038#include <sys/eventfd.h>
Steven Morelandcde5d532020-12-02 23:34:15 +000039#include <sys/prctl.h>
Dan Stoza2537db72017-04-07 16:32:38 -070040
Dan Stozad630e522016-12-01 15:16:31 -080041using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
42
43namespace android {
44namespace tests {
45
Steven Morelandcde5d532020-12-02 23:34:15 +000046static const String16 kServiceName("SafeInterfaceTest");
47
Dan Stoza81ea3ef2017-04-07 15:00:18 -070048enum class TestEnum : uint32_t {
49 INVALID = 0,
50 INITIAL = 1,
51 FINAL = 2,
52};
53
Dan Stozad630e522016-12-01 15:16:31 -080054// This class serves two purposes:
55// 1) It ensures that the implementation doesn't require copying or moving the data (for
56// efficiency purposes)
57// 2) It tests that Parcelables can be passed correctly
58class NoCopyNoMove : public Parcelable {
59public:
60 NoCopyNoMove() = default;
61 explicit NoCopyNoMove(int32_t value) : mValue(value) {}
62 ~NoCopyNoMove() override = default;
63
64 // Not copyable
65 NoCopyNoMove(const NoCopyNoMove&) = delete;
66 NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
67
68 // Not movable
69 NoCopyNoMove(NoCopyNoMove&&) = delete;
70 NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
71
72 // Parcelable interface
73 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
74 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
75
76 int32_t getValue() const { return mValue; }
77 void setValue(int32_t value) { mValue = value; }
78
79private:
80 int32_t mValue = 0;
Steven Moreland573adc12019-07-17 13:29:06 -070081 __attribute__((unused)) uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
Dan Stozad630e522016-12-01 15:16:31 -080082};
83
Dan Stozadf614ae2017-03-28 17:02:05 -070084struct TestFlattenable : Flattenable<TestFlattenable> {
85 TestFlattenable() = default;
86 explicit TestFlattenable(int32_t v) : value(v) {}
87
88 // Flattenable protocol
89 size_t getFlattenedSize() const { return sizeof(value); }
90 size_t getFdCount() const { return 0; }
91 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
92 FlattenableUtils::write(buffer, size, value);
93 return NO_ERROR;
94 }
95 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
96 FlattenableUtils::read(buffer, size, value);
97 return NO_ERROR;
98 }
99
100 int32_t value = 0;
101};
102
Dan Stozad630e522016-12-01 15:16:31 -0800103struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
104 TestLightFlattenable() = default;
105 explicit TestLightFlattenable(int32_t v) : value(v) {}
106 int32_t value = 0;
107};
108
Dan Stoza6dd325b2017-04-07 14:31:51 -0700109// It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
110// but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
111// base class
112class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
113 public LightRefBase<TestLightRefBaseFlattenable> {
114public:
115 TestLightRefBaseFlattenable() = default;
116 explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
117
118 // Flattenable protocol
119 size_t getFlattenedSize() const { return sizeof(value); }
120 size_t getFdCount() const { return 0; }
121 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
122 FlattenableUtils::write(buffer, size, value);
123 return NO_ERROR;
124 }
125 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
126 FlattenableUtils::read(buffer, size, value);
127 return NO_ERROR;
128 }
129
130 int32_t value = 0;
131};
132
Dan Stoza1af8a882017-04-10 13:28:54 -0700133class TestParcelable : public Parcelable {
134public:
135 TestParcelable() = default;
136 explicit TestParcelable(int32_t value) : mValue(value) {}
137 TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
138 TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
139
140 // Parcelable interface
141 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
142 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
143
144 int32_t getValue() const { return mValue; }
145 void setValue(int32_t value) { mValue = value; }
146
147private:
148 int32_t mValue = 0;
149};
150
Dan Stozad630e522016-12-01 15:16:31 -0800151class ExitOnDeath : public IBinder::DeathRecipient {
152public:
153 ~ExitOnDeath() override = default;
154
155 void binderDied(const wp<IBinder>& /*who*/) override {
156 ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
157 exit(0);
158 }
159};
160
161// This callback class is used to test both one-way transactions and that sp<IInterface> can be
162// passed correctly
163class ICallback : public IInterface {
164public:
165 DECLARE_META_INTERFACE(Callback)
166
167 enum class Tag : uint32_t {
168 OnCallback = IBinder::FIRST_CALL_TRANSACTION,
169 Last,
170 };
171
172 virtual void onCallback(int32_t aPlusOne) = 0;
173};
174
175class BpCallback : public SafeBpInterface<ICallback> {
176public:
177 explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
178
179 void onCallback(int32_t aPlusOne) override {
180 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
181 return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
182 }
183
184private:
185 static constexpr const char* getLogTag() { return "BpCallback"; }
186};
187
188#pragma clang diagnostic push
189#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900190IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback")
Dan Stozad630e522016-12-01 15:16:31 -0800191#pragma clang diagnostic pop
192
193class BnCallback : public SafeBnInterface<ICallback> {
194public:
195 BnCallback() : SafeBnInterface("BnCallback") {}
196
197 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
198 uint32_t /*flags*/) override {
199 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
200 EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
201 ICallback::Tag tag = static_cast<ICallback::Tag>(code);
202 switch (tag) {
203 case ICallback::Tag::OnCallback: {
204 return callLocalAsync(data, reply, &ICallback::onCallback);
205 }
206 case ICallback::Tag::Last:
207 // Should not be possible because of the asserts at the beginning of the method
208 [&]() { FAIL(); }();
209 return UNKNOWN_ERROR;
210 }
211 }
212};
213
214class ISafeInterfaceTest : public IInterface {
215public:
216 DECLARE_META_INTERFACE(SafeInterfaceTest)
217
218 enum class Tag : uint32_t {
219 SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
220 ReturnsNoMemory,
221 LogicalNot,
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700222 ModifyEnum,
Dan Stozadf614ae2017-03-28 17:02:05 -0700223 IncrementFlattenable,
Dan Stozad630e522016-12-01 15:16:31 -0800224 IncrementLightFlattenable,
Dan Stoza6dd325b2017-04-07 14:31:51 -0700225 IncrementLightRefBaseFlattenable,
Dan Stoza2537db72017-04-07 16:32:38 -0700226 IncrementNativeHandle,
Dan Stozad630e522016-12-01 15:16:31 -0800227 IncrementNoCopyNoMove,
Dan Stoza1af8a882017-04-10 13:28:54 -0700228 IncrementParcelableVector,
Elliott Hughesd7657972021-04-12 15:31:22 -0700229 DoubleString,
Dan Stozad630e522016-12-01 15:16:31 -0800230 CallMeBack,
231 IncrementInt32,
232 IncrementUint32,
Dan Stoza662a8992017-04-06 16:18:39 -0700233 IncrementInt64,
234 IncrementUint64,
Dan Stoza4c6d9732018-11-14 10:18:14 -0800235 IncrementFloat,
Dan Stozad630e522016-12-01 15:16:31 -0800236 IncrementTwo,
237 Last,
238 };
239
240 // This is primarily so that the remote service dies when the test does, but it also serves to
241 // test the handling of sp<IBinder> and non-const methods
242 virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
243
244 // This is the most basic test since it doesn't require parceling any arguments
245 virtual status_t returnsNoMemory() const = 0;
246
247 // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
248 virtual status_t logicalNot(bool a, bool* notA) const = 0;
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700249 virtual status_t modifyEnum(TestEnum a, TestEnum* b) const = 0;
Dan Stozadf614ae2017-03-28 17:02:05 -0700250 virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800251 virtual status_t increment(const TestLightFlattenable& a,
252 TestLightFlattenable* aPlusOne) const = 0;
Dan Stoza6dd325b2017-04-07 14:31:51 -0700253 virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
254 sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
Dan Stoza2537db72017-04-07 16:32:38 -0700255 virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800256 virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
Dan Stoza1af8a882017-04-10 13:28:54 -0700257 virtual status_t increment(const std::vector<TestParcelable>& a,
258 std::vector<TestParcelable>* aPlusOne) const = 0;
Elliott Hughesd7657972021-04-12 15:31:22 -0700259 virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800260 // As mentioned above, sp<IBinder> is already tested by setDeathToken
261 virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
262 virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
263 virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
Dan Stoza662a8992017-04-06 16:18:39 -0700264 virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
265 virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
Dan Stoza4c6d9732018-11-14 10:18:14 -0800266 virtual status_t increment(float a, float* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800267
268 // This tests that input/output parameter interleaving works correctly
269 virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
270 int32_t* bPlusOne) const = 0;
271};
272
273class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
274public:
275 explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
276 : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
277
278 status_t setDeathToken(const sp<IBinder>& token) override {
279 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
280 return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
281 }
282 status_t returnsNoMemory() const override {
283 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
284 return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
285 }
286 status_t logicalNot(bool a, bool* notA) const override {
287 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
288 return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
289 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700290 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
291 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
292 return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b);
293 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700294 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
295 using Signature =
296 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
297 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
298 return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
299 }
Dan Stozad630e522016-12-01 15:16:31 -0800300 status_t increment(const TestLightFlattenable& a,
301 TestLightFlattenable* aPlusOne) const override {
302 using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
303 TestLightFlattenable*) const;
304 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
305 return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
306 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700307 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
308 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
309 using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
310 sp<TestLightRefBaseFlattenable>*) const;
311 return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
312 }
Dan Stoza2537db72017-04-07 16:32:38 -0700313 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
314 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
315 using Signature =
316 status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&, sp<NativeHandle>*) const;
317 return callRemote<Signature>(Tag::IncrementNativeHandle, a, aPlusOne);
318 }
Dan Stozad630e522016-12-01 15:16:31 -0800319 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
320 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
321 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
322 NoCopyNoMove* aPlusOne) const;
323 return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
324 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700325 status_t increment(const std::vector<TestParcelable>& a,
326 std::vector<TestParcelable>* aPlusOne) const override {
327 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
328 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
329 std::vector<TestParcelable>*);
330 return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
331 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700332 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800333 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700334 return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
335 doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800336 }
337 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
338 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
339 return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
340 a);
341 }
342 status_t increment(int32_t a, int32_t* aPlusOne) const override {
343 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
344 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
345 return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
346 }
347 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
348 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
349 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
350 return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
351 }
Dan Stoza662a8992017-04-06 16:18:39 -0700352 status_t increment(int64_t a, int64_t* aPlusOne) const override {
353 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
354 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
355 return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
356 }
357 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
358 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
359 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
360 return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
361 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800362 status_t increment(float a, float* aPlusOne) const override {
363 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
364 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
365 return callRemote<Signature>(Tag::IncrementFloat, a, aPlusOne);
366 }
Dan Stozad630e522016-12-01 15:16:31 -0800367 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
368 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
369 using Signature =
370 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
371 return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
372 }
373
374private:
375 static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
376};
377
378#pragma clang diagnostic push
379#pragma clang diagnostic ignored "-Wexit-time-destructors"
Jooyung Hanc91e3cb2020-11-25 06:38:17 +0900380IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest")
Dan Stozad630e522016-12-01 15:16:31 -0800381
382static sp<IBinder::DeathRecipient> getDeathRecipient() {
383 static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
384 return recipient;
385}
386#pragma clang diagnostic pop
387
388class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
389public:
390 BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
391
392 status_t setDeathToken(const sp<IBinder>& token) override {
393 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
394 token->linkToDeath(getDeathRecipient());
395 return NO_ERROR;
396 }
397 status_t returnsNoMemory() const override {
398 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
399 return NO_MEMORY;
400 }
401 status_t logicalNot(bool a, bool* notA) const override {
402 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
403 *notA = !a;
404 return NO_ERROR;
405 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700406 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
407 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
408 *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID;
409 return NO_ERROR;
410 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700411 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
412 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
413 aPlusOne->value = a.value + 1;
414 return NO_ERROR;
415 }
Dan Stozad630e522016-12-01 15:16:31 -0800416 status_t increment(const TestLightFlattenable& a,
417 TestLightFlattenable* aPlusOne) const override {
418 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
419 aPlusOne->value = a.value + 1;
420 return NO_ERROR;
421 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700422 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
423 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
424 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
425 *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
426 return NO_ERROR;
427 }
Dan Stoza2537db72017-04-07 16:32:38 -0700428 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
429 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
430 native_handle* rawHandle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
431 if (rawHandle == nullptr) return NO_MEMORY;
432
433 // Copy the fd over directly
434 rawHandle->data[0] = dup(a->handle()->data[0]);
435
436 // Increment the int
437 rawHandle->data[1] = a->handle()->data[1] + 1;
438
439 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
440 // the native_handle when it goes out of scope
441 *aPlusOne = NativeHandle::create(rawHandle, true);
442 return NO_ERROR;
443 }
Dan Stozad630e522016-12-01 15:16:31 -0800444 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
445 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
446 aPlusOne->setValue(a.getValue() + 1);
447 return NO_ERROR;
448 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700449 status_t increment(const std::vector<TestParcelable>& a,
450 std::vector<TestParcelable>* aPlusOne) const override {
451 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
452 aPlusOne->resize(a.size());
453 for (size_t i = 0; i < a.size(); ++i) {
454 (*aPlusOne)[i].setValue(a[i].getValue() + 1);
455 }
456 return NO_ERROR;
457 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700458 status_t doubleString(const String8& str, String8* doubleStr) const override {
Dan Stozad630e522016-12-01 15:16:31 -0800459 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
Elliott Hughesd7657972021-04-12 15:31:22 -0700460 *doubleStr = str + str;
Dan Stozad630e522016-12-01 15:16:31 -0800461 return NO_ERROR;
462 }
463 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
464 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
465 callback->onCallback(a + 1);
466 }
467 status_t increment(int32_t a, int32_t* aPlusOne) const override {
468 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
469 *aPlusOne = a + 1;
470 return NO_ERROR;
471 }
472 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
473 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
474 *aPlusOne = a + 1;
475 return NO_ERROR;
476 }
Dan Stoza662a8992017-04-06 16:18:39 -0700477 status_t increment(int64_t a, int64_t* aPlusOne) const override {
478 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
479 *aPlusOne = a + 1;
480 return NO_ERROR;
481 }
482 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
483 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
484 *aPlusOne = a + 1;
485 return NO_ERROR;
486 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800487 status_t increment(float a, float* aPlusOne) const override {
488 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
489 *aPlusOne = a + 1.0f;
490 return NO_ERROR;
491 }
Dan Stozad630e522016-12-01 15:16:31 -0800492 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
493 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
494 *aPlusOne = a + 1;
495 *bPlusOne = b + 1;
496 return NO_ERROR;
497 }
498
499 // BnInterface
500 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
501 uint32_t /*flags*/) override {
502 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
503 EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
504 ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
505 switch (tag) {
506 case ISafeInterfaceTest::Tag::SetDeathToken: {
507 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
508 }
509 case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
510 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
511 }
512 case ISafeInterfaceTest::Tag::LogicalNot: {
513 return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
514 }
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700515 case ISafeInterfaceTest::Tag::ModifyEnum: {
516 return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum);
517 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700518 case ISafeInterfaceTest::Tag::IncrementFlattenable: {
519 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
520 TestFlattenable* aPlusOne) const;
521 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
522 }
Dan Stozad630e522016-12-01 15:16:31 -0800523 case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
524 using Signature =
525 status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
526 TestLightFlattenable* aPlusOne) const;
527 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
528 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700529 case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
530 using Signature =
531 status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
532 sp<TestLightRefBaseFlattenable>*) const;
533 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
534 }
Dan Stoza2537db72017-04-07 16:32:38 -0700535 case ISafeInterfaceTest::Tag::IncrementNativeHandle: {
536 using Signature = status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&,
537 sp<NativeHandle>*) const;
538 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
539 }
Dan Stozad630e522016-12-01 15:16:31 -0800540 case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
541 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
542 NoCopyNoMove* aPlusOne) const;
543 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
544 }
Dan Stoza1af8a882017-04-10 13:28:54 -0700545 case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
546 using Signature =
547 status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
548 std::vector<TestParcelable>*) const;
549 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
550 }
Elliott Hughesd7657972021-04-12 15:31:22 -0700551 case ISafeInterfaceTest::Tag::DoubleString: {
552 return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
Dan Stozad630e522016-12-01 15:16:31 -0800553 }
554 case ISafeInterfaceTest::Tag::CallMeBack: {
555 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
556 }
557 case ISafeInterfaceTest::Tag::IncrementInt32: {
558 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
559 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
560 }
561 case ISafeInterfaceTest::Tag::IncrementUint32: {
562 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
563 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
564 }
Dan Stoza662a8992017-04-06 16:18:39 -0700565 case ISafeInterfaceTest::Tag::IncrementInt64: {
566 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
567 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
568 }
569 case ISafeInterfaceTest::Tag::IncrementUint64: {
570 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
571 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
572 }
Dan Stoza4c6d9732018-11-14 10:18:14 -0800573 case ISafeInterfaceTest::Tag::IncrementFloat: {
574 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
575 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
576 }
Dan Stozad630e522016-12-01 15:16:31 -0800577 case ISafeInterfaceTest::Tag::IncrementTwo: {
578 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
579 int32_t*) const;
580 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
581 }
582 case ISafeInterfaceTest::Tag::Last:
583 // Should not be possible because of the asserts at the beginning of the method
584 [&]() { FAIL(); }();
585 return UNKNOWN_ERROR;
586 }
587 }
588
589private:
590 static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
591};
592
593class SafeInterfaceTest : public ::testing::Test {
594public:
595 SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
596 ProcessState::self()->startThreadPool();
597 }
598 ~SafeInterfaceTest() override = default;
599
600protected:
601 sp<ISafeInterfaceTest> mSafeInterfaceTest;
602
603private:
604 static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
605
606 sp<ISafeInterfaceTest> getRemoteService() {
Steven Morelandcde5d532020-12-02 23:34:15 +0000607 sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
608 sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
609 EXPECT_TRUE(iface != nullptr);
Dan Stozad630e522016-12-01 15:16:31 -0800610
Steven Morelandcde5d532020-12-02 23:34:15 +0000611 iface->setDeathToken(new BBinder);
Dan Stozad630e522016-12-01 15:16:31 -0800612
Steven Morelandcde5d532020-12-02 23:34:15 +0000613 return iface;
Dan Stozad630e522016-12-01 15:16:31 -0800614 }
615};
616
617TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
618 status_t result = mSafeInterfaceTest->returnsNoMemory();
619 ASSERT_EQ(NO_MEMORY, result);
620}
621
622TEST_F(SafeInterfaceTest, TestLogicalNot) {
623 const bool a = true;
624 bool notA = true;
625 status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
626 ASSERT_EQ(NO_ERROR, result);
627 ASSERT_EQ(!a, notA);
628 // Test both since we don't want to accidentally catch a default false somewhere
629 const bool b = false;
630 bool notB = false;
631 result = mSafeInterfaceTest->logicalNot(b, &notB);
632 ASSERT_EQ(NO_ERROR, result);
633 ASSERT_EQ(!b, notB);
634}
635
Dan Stoza81ea3ef2017-04-07 15:00:18 -0700636TEST_F(SafeInterfaceTest, TestModifyEnum) {
637 const TestEnum a = TestEnum::INITIAL;
638 TestEnum b = TestEnum::INVALID;
639 status_t result = mSafeInterfaceTest->modifyEnum(a, &b);
640 ASSERT_EQ(NO_ERROR, result);
641 ASSERT_EQ(TestEnum::FINAL, b);
642}
643
Dan Stozadf614ae2017-03-28 17:02:05 -0700644TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
645 const TestFlattenable a{1};
646 TestFlattenable aPlusOne{0};
647 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
648 ASSERT_EQ(NO_ERROR, result);
649 ASSERT_EQ(a.value + 1, aPlusOne.value);
650}
651
Dan Stozad630e522016-12-01 15:16:31 -0800652TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
653 const TestLightFlattenable a{1};
654 TestLightFlattenable aPlusOne{0};
655 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
656 ASSERT_EQ(NO_ERROR, result);
657 ASSERT_EQ(a.value + 1, aPlusOne.value);
658}
659
Dan Stoza6dd325b2017-04-07 14:31:51 -0700660TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
661 sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
662 sp<TestLightRefBaseFlattenable> aPlusOne;
663 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
664 ASSERT_EQ(NO_ERROR, result);
665 ASSERT_NE(nullptr, aPlusOne.get());
666 ASSERT_EQ(a->value + 1, aPlusOne->value);
667}
668
Dan Stoza2537db72017-04-07 16:32:38 -0700669namespace { // Anonymous namespace
670
671bool fdsAreEquivalent(int a, int b) {
672 struct stat statA {};
673 struct stat statB {};
674 if (fstat(a, &statA) != 0) return false;
675 if (fstat(b, &statB) != 0) return false;
676 return (statA.st_dev == statB.st_dev) && (statA.st_ino == statB.st_ino);
677}
678
679} // Anonymous namespace
680
681TEST_F(SafeInterfaceTest, TestIncrementNativeHandle) {
682 // Create an fd we can use to send and receive from the remote process
683 base::unique_fd eventFd{eventfd(0 /*initval*/, 0 /*flags*/)};
684 ASSERT_NE(-1, eventFd);
685
686 // Determine the maximum number of fds this process can have open
687 struct rlimit limit {};
688 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &limit));
689 uint32_t maxFds = static_cast<uint32_t>(limit.rlim_cur);
690
691 // Perform this test enough times to rule out fd leaks
692 for (uint32_t iter = 0; iter < (2 * maxFds); ++iter) {
693 native_handle* handle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
694 ASSERT_NE(nullptr, handle);
695 handle->data[0] = dup(eventFd.get());
696 handle->data[1] = 1;
697
698 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
699 // the native_handle when it goes out of scope
700 sp<NativeHandle> a = NativeHandle::create(handle, true);
701
702 sp<NativeHandle> aPlusOne;
703 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
704 ASSERT_EQ(NO_ERROR, result);
705 ASSERT_TRUE(fdsAreEquivalent(a->handle()->data[0], aPlusOne->handle()->data[0]));
706 ASSERT_EQ(a->handle()->data[1] + 1, aPlusOne->handle()->data[1]);
707 }
708}
709
Dan Stozad630e522016-12-01 15:16:31 -0800710TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
711 const NoCopyNoMove a{1};
712 NoCopyNoMove aPlusOne{0};
713 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
714 ASSERT_EQ(NO_ERROR, result);
715 ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
716}
717
Dan Stoza1af8a882017-04-10 13:28:54 -0700718TEST_F(SafeInterfaceTest, TestIncremementParcelableVector) {
719 const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
720 std::vector<TestParcelable> aPlusOne;
721 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
Steven Moreland573adc12019-07-17 13:29:06 -0700722 ASSERT_EQ(NO_ERROR, result);
Dan Stoza1af8a882017-04-10 13:28:54 -0700723 ASSERT_EQ(a.size(), aPlusOne.size());
724 for (size_t i = 0; i < a.size(); ++i) {
725 ASSERT_EQ(a[i].getValue() + 1, aPlusOne[i].getValue());
726 }
727}
728
Elliott Hughesd7657972021-04-12 15:31:22 -0700729TEST_F(SafeInterfaceTest, TestDoubleString) {
730 const String8 str{"asdf"};
731 String8 doubleStr;
732 status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
Dan Stozad630e522016-12-01 15:16:31 -0800733 ASSERT_EQ(NO_ERROR, result);
Elliott Hughesd7657972021-04-12 15:31:22 -0700734 ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
Dan Stozad630e522016-12-01 15:16:31 -0800735}
736
737TEST_F(SafeInterfaceTest, TestCallMeBack) {
738 class CallbackReceiver : public BnCallback {
739 public:
740 void onCallback(int32_t aPlusOne) override {
741 ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
742 std::unique_lock<decltype(mMutex)> lock(mMutex);
743 mValue = aPlusOne;
744 mCondition.notify_one();
745 }
746
747 std::optional<int32_t> waitForCallback() {
748 std::unique_lock<decltype(mMutex)> lock(mMutex);
749 bool success =
750 mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
751 return success ? mValue : std::nullopt;
752 }
753
754 private:
755 std::mutex mMutex;
756 std::condition_variable mCondition;
757 std::optional<int32_t> mValue;
758 };
759
760 sp<CallbackReceiver> receiver = new CallbackReceiver;
761 const int32_t a = 1;
762 mSafeInterfaceTest->callMeBack(receiver, a);
763 auto result = receiver->waitForCallback();
764 ASSERT_TRUE(result);
765 ASSERT_EQ(a + 1, *result);
766}
767
768TEST_F(SafeInterfaceTest, TestIncrementInt32) {
769 const int32_t a = 1;
770 int32_t aPlusOne = 0;
771 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
772 ASSERT_EQ(NO_ERROR, result);
773 ASSERT_EQ(a + 1, aPlusOne);
774}
775
776TEST_F(SafeInterfaceTest, TestIncrementUint32) {
777 const uint32_t a = 1;
778 uint32_t aPlusOne = 0;
779 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
780 ASSERT_EQ(NO_ERROR, result);
781 ASSERT_EQ(a + 1, aPlusOne);
782}
783
Dan Stoza662a8992017-04-06 16:18:39 -0700784TEST_F(SafeInterfaceTest, TestIncrementInt64) {
785 const int64_t a = 1;
786 int64_t aPlusOne = 0;
787 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
788 ASSERT_EQ(NO_ERROR, result);
789 ASSERT_EQ(a + 1, aPlusOne);
790}
791
792TEST_F(SafeInterfaceTest, TestIncrementUint64) {
793 const uint64_t a = 1;
794 uint64_t aPlusOne = 0;
795 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
796 ASSERT_EQ(NO_ERROR, result);
797 ASSERT_EQ(a + 1, aPlusOne);
798}
799
Dan Stoza4c6d9732018-11-14 10:18:14 -0800800TEST_F(SafeInterfaceTest, TestIncrementFloat) {
801 const float a = 1.0f;
802 float aPlusOne = 0.0f;
803 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
804 ASSERT_EQ(NO_ERROR, result);
805 ASSERT_EQ(a + 1.0f, aPlusOne);
806}
807
Dan Stozad630e522016-12-01 15:16:31 -0800808TEST_F(SafeInterfaceTest, TestIncrementTwo) {
809 const int32_t a = 1;
810 int32_t aPlusOne = 0;
811 const int32_t b = 2;
812 int32_t bPlusOne = 0;
813 status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
814 ASSERT_EQ(NO_ERROR, result);
815 ASSERT_EQ(a + 1, aPlusOne);
816 ASSERT_EQ(b + 1, bPlusOne);
817}
818
Steven Morelandcde5d532020-12-02 23:34:15 +0000819extern "C" int main(int argc, char **argv) {
820 testing::InitGoogleTest(&argc, argv);
821
822 if (fork() == 0) {
823 prctl(PR_SET_PDEATHSIG, SIGHUP);
824 sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
825 status_t status = defaultServiceManager()->addService(kServiceName, nativeService);
826 if (status != OK) {
827 ALOG(LOG_INFO, "SafeInterfaceServer", "could not register");
828 return EXIT_FAILURE;
829 }
830 IPCThreadState::self()->joinThreadPool();
831 return EXIT_FAILURE;
832 }
833
834 return RUN_ALL_TESTS();
835}
836
Dan Stozad630e522016-12-01 15:16:31 -0800837} // namespace tests
838} // namespace android