1 /*
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
31 #include <utils/LightRefBase.h>
32 #include <utils/NativeHandle.h>
33
34 #include <cutils/native_handle.h>
35
36 #include <optional>
37
38 #include <sys/eventfd.h>
39
40 using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
41
42 namespace android {
43 namespace tests {
44
45 enum class TestEnum : uint32_t {
46 INVALID = 0,
47 INITIAL = 1,
48 FINAL = 2,
49 };
50
51 // This class serves two purposes:
52 // 1) It ensures that the implementation doesn't require copying or moving the data (for
53 // efficiency purposes)
54 // 2) It tests that Parcelables can be passed correctly
55 class NoCopyNoMove : public Parcelable {
56 public:
57 NoCopyNoMove() = default;
NoCopyNoMove(int32_t value)58 explicit NoCopyNoMove(int32_t value) : mValue(value) {}
59 ~NoCopyNoMove() override = default;
60
61 // Not copyable
62 NoCopyNoMove(const NoCopyNoMove&) = delete;
63 NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
64
65 // Not movable
66 NoCopyNoMove(NoCopyNoMove&&) = delete;
67 NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
68
69 // Parcelable interface
writeToParcel(Parcel * parcel) const70 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
readFromParcel(const Parcel * parcel)71 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
72
getValue() const73 int32_t getValue() const { return mValue; }
setValue(int32_t value)74 void setValue(int32_t value) { mValue = value; }
75
76 private:
77 int32_t mValue = 0;
78 uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
79 };
80
81 struct TestFlattenable : Flattenable<TestFlattenable> {
82 TestFlattenable() = default;
TestFlattenableandroid::tests::TestFlattenable83 explicit TestFlattenable(int32_t v) : value(v) {}
84
85 // Flattenable protocol
getFlattenedSizeandroid::tests::TestFlattenable86 size_t getFlattenedSize() const { return sizeof(value); }
getFdCountandroid::tests::TestFlattenable87 size_t getFdCount() const { return 0; }
flattenandroid::tests::TestFlattenable88 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
89 FlattenableUtils::write(buffer, size, value);
90 return NO_ERROR;
91 }
unflattenandroid::tests::TestFlattenable92 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
93 FlattenableUtils::read(buffer, size, value);
94 return NO_ERROR;
95 }
96
97 int32_t value = 0;
98 };
99
100 struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
101 TestLightFlattenable() = default;
TestLightFlattenableandroid::tests::TestLightFlattenable102 explicit TestLightFlattenable(int32_t v) : value(v) {}
103 int32_t value = 0;
104 };
105
106 // It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
107 // but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
108 // base class
109 class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
110 public LightRefBase<TestLightRefBaseFlattenable> {
111 public:
112 TestLightRefBaseFlattenable() = default;
TestLightRefBaseFlattenable(int32_t v)113 explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
114
115 // Flattenable protocol
getFlattenedSize() const116 size_t getFlattenedSize() const { return sizeof(value); }
getFdCount() const117 size_t getFdCount() const { return 0; }
flatten(void * & buffer,size_t & size,int * &,size_t &) const118 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
119 FlattenableUtils::write(buffer, size, value);
120 return NO_ERROR;
121 }
unflatten(void const * & buffer,size_t & size,int const * &,size_t &)122 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
123 FlattenableUtils::read(buffer, size, value);
124 return NO_ERROR;
125 }
126
127 int32_t value = 0;
128 };
129
130 class TestParcelable : public Parcelable {
131 public:
132 TestParcelable() = default;
TestParcelable(int32_t value)133 explicit TestParcelable(int32_t value) : mValue(value) {}
TestParcelable(const TestParcelable & other)134 TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
TestParcelable(TestParcelable && other)135 TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
136
137 // Parcelable interface
writeToParcel(Parcel * parcel) const138 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
readFromParcel(const Parcel * parcel)139 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
140
getValue() const141 int32_t getValue() const { return mValue; }
setValue(int32_t value)142 void setValue(int32_t value) { mValue = value; }
143
144 private:
145 int32_t mValue = 0;
146 };
147
148 class ExitOnDeath : public IBinder::DeathRecipient {
149 public:
150 ~ExitOnDeath() override = default;
151
binderDied(const wp<IBinder> &)152 void binderDied(const wp<IBinder>& /*who*/) override {
153 ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
154 exit(0);
155 }
156 };
157
158 // This callback class is used to test both one-way transactions and that sp<IInterface> can be
159 // passed correctly
160 class ICallback : public IInterface {
161 public:
162 DECLARE_META_INTERFACE(Callback)
163
164 enum class Tag : uint32_t {
165 OnCallback = IBinder::FIRST_CALL_TRANSACTION,
166 Last,
167 };
168
169 virtual void onCallback(int32_t aPlusOne) = 0;
170 };
171
172 class BpCallback : public SafeBpInterface<ICallback> {
173 public:
BpCallback(const sp<IBinder> & impl)174 explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
175
onCallback(int32_t aPlusOne)176 void onCallback(int32_t aPlusOne) override {
177 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
178 return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
179 }
180
181 private:
getLogTag()182 static constexpr const char* getLogTag() { return "BpCallback"; }
183 };
184
185 #pragma clang diagnostic push
186 #pragma clang diagnostic ignored "-Wexit-time-destructors"
187 IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback");
188 #pragma clang diagnostic pop
189
190 class BnCallback : public SafeBnInterface<ICallback> {
191 public:
BnCallback()192 BnCallback() : SafeBnInterface("BnCallback") {}
193
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)194 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
195 uint32_t /*flags*/) override {
196 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
197 EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
198 ICallback::Tag tag = static_cast<ICallback::Tag>(code);
199 switch (tag) {
200 case ICallback::Tag::OnCallback: {
201 return callLocalAsync(data, reply, &ICallback::onCallback);
202 }
203 case ICallback::Tag::Last:
204 // Should not be possible because of the asserts at the beginning of the method
205 [&]() { FAIL(); }();
206 return UNKNOWN_ERROR;
207 }
208 }
209 };
210
211 class ISafeInterfaceTest : public IInterface {
212 public:
213 DECLARE_META_INTERFACE(SafeInterfaceTest)
214
215 enum class Tag : uint32_t {
216 SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
217 ReturnsNoMemory,
218 LogicalNot,
219 ModifyEnum,
220 IncrementFlattenable,
221 IncrementLightFlattenable,
222 IncrementLightRefBaseFlattenable,
223 IncrementNativeHandle,
224 IncrementNoCopyNoMove,
225 IncrementParcelableVector,
226 ToUpper,
227 CallMeBack,
228 IncrementInt32,
229 IncrementUint32,
230 IncrementInt64,
231 IncrementUint64,
232 IncrementTwo,
233 Last,
234 };
235
236 // This is primarily so that the remote service dies when the test does, but it also serves to
237 // test the handling of sp<IBinder> and non-const methods
238 virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
239
240 // This is the most basic test since it doesn't require parceling any arguments
241 virtual status_t returnsNoMemory() const = 0;
242
243 // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
244 virtual status_t logicalNot(bool a, bool* notA) const = 0;
245 virtual status_t modifyEnum(TestEnum a, TestEnum* b) const = 0;
246 virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
247 virtual status_t increment(const TestLightFlattenable& a,
248 TestLightFlattenable* aPlusOne) const = 0;
249 virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
250 sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
251 virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
252 virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
253 virtual status_t increment(const std::vector<TestParcelable>& a,
254 std::vector<TestParcelable>* aPlusOne) const = 0;
255 virtual status_t toUpper(const String8& str, String8* upperStr) const = 0;
256 // As mentioned above, sp<IBinder> is already tested by setDeathToken
257 virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
258 virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
259 virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
260 virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
261 virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
262
263 // This tests that input/output parameter interleaving works correctly
264 virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
265 int32_t* bPlusOne) const = 0;
266 };
267
268 class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
269 public:
BpSafeInterfaceTest(const sp<IBinder> & impl)270 explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
271 : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
272
setDeathToken(const sp<IBinder> & token)273 status_t setDeathToken(const sp<IBinder>& token) override {
274 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
275 return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
276 }
returnsNoMemory() const277 status_t returnsNoMemory() const override {
278 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
279 return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
280 }
logicalNot(bool a,bool * notA) const281 status_t logicalNot(bool a, bool* notA) const override {
282 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
283 return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
284 }
modifyEnum(TestEnum a,TestEnum * b) const285 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
286 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
287 return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b);
288 }
increment(const TestFlattenable & a,TestFlattenable * aPlusOne) const289 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
290 using Signature =
291 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
292 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
293 return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
294 }
increment(const TestLightFlattenable & a,TestLightFlattenable * aPlusOne) const295 status_t increment(const TestLightFlattenable& a,
296 TestLightFlattenable* aPlusOne) const override {
297 using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
298 TestLightFlattenable*) const;
299 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
300 return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
301 }
increment(const sp<TestLightRefBaseFlattenable> & a,sp<TestLightRefBaseFlattenable> * aPlusOne) const302 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
303 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
304 using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
305 sp<TestLightRefBaseFlattenable>*) const;
306 return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
307 }
increment(const sp<NativeHandle> & a,sp<NativeHandle> * aPlusOne) const308 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
309 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
310 using Signature =
311 status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&, sp<NativeHandle>*) const;
312 return callRemote<Signature>(Tag::IncrementNativeHandle, a, aPlusOne);
313 }
increment(const NoCopyNoMove & a,NoCopyNoMove * aPlusOne) const314 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
315 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
316 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
317 NoCopyNoMove* aPlusOne) const;
318 return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
319 }
increment(const std::vector<TestParcelable> & a,std::vector<TestParcelable> * aPlusOne) const320 status_t increment(const std::vector<TestParcelable>& a,
321 std::vector<TestParcelable>* aPlusOne) const override {
322 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
323 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
324 std::vector<TestParcelable>*);
325 return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
326 }
toUpper(const String8 & str,String8 * upperStr) const327 status_t toUpper(const String8& str, String8* upperStr) const override {
328 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
329 return callRemote<decltype(&ISafeInterfaceTest::toUpper)>(Tag::ToUpper, str, upperStr);
330 }
callMeBack(const sp<ICallback> & callback,int32_t a) const331 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
332 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
333 return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
334 a);
335 }
increment(int32_t a,int32_t * aPlusOne) const336 status_t increment(int32_t a, int32_t* aPlusOne) const override {
337 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
338 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
339 return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
340 }
increment(uint32_t a,uint32_t * aPlusOne) const341 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
342 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
343 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
344 return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
345 }
increment(int64_t a,int64_t * aPlusOne) const346 status_t increment(int64_t a, int64_t* aPlusOne) const override {
347 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
348 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
349 return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
350 }
increment(uint64_t a,uint64_t * aPlusOne) const351 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
352 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
353 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
354 return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
355 }
increment(int32_t a,int32_t * aPlusOne,int32_t b,int32_t * bPlusOne) const356 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
357 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
358 using Signature =
359 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
360 return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
361 }
362
363 private:
getLogTag()364 static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
365 };
366
367 #pragma clang diagnostic push
368 #pragma clang diagnostic ignored "-Wexit-time-destructors"
369 IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest");
370
getDeathRecipient()371 static sp<IBinder::DeathRecipient> getDeathRecipient() {
372 static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
373 return recipient;
374 }
375 #pragma clang diagnostic pop
376
377 class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
378 public:
BnSafeInterfaceTest()379 BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
380
setDeathToken(const sp<IBinder> & token)381 status_t setDeathToken(const sp<IBinder>& token) override {
382 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
383 token->linkToDeath(getDeathRecipient());
384 return NO_ERROR;
385 }
returnsNoMemory() const386 status_t returnsNoMemory() const override {
387 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
388 return NO_MEMORY;
389 }
logicalNot(bool a,bool * notA) const390 status_t logicalNot(bool a, bool* notA) const override {
391 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
392 *notA = !a;
393 return NO_ERROR;
394 }
modifyEnum(TestEnum a,TestEnum * b) const395 status_t modifyEnum(TestEnum a, TestEnum* b) const override {
396 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
397 *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID;
398 return NO_ERROR;
399 }
increment(const TestFlattenable & a,TestFlattenable * aPlusOne) const400 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
401 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
402 aPlusOne->value = a.value + 1;
403 return NO_ERROR;
404 }
increment(const TestLightFlattenable & a,TestLightFlattenable * aPlusOne) const405 status_t increment(const TestLightFlattenable& a,
406 TestLightFlattenable* aPlusOne) const override {
407 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
408 aPlusOne->value = a.value + 1;
409 return NO_ERROR;
410 }
increment(const sp<TestLightRefBaseFlattenable> & a,sp<TestLightRefBaseFlattenable> * aPlusOne) const411 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
412 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
413 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
414 *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
415 return NO_ERROR;
416 }
increment(const sp<NativeHandle> & a,sp<NativeHandle> * aPlusOne) const417 status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
418 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
419 native_handle* rawHandle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
420 if (rawHandle == nullptr) return NO_MEMORY;
421
422 // Copy the fd over directly
423 rawHandle->data[0] = dup(a->handle()->data[0]);
424
425 // Increment the int
426 rawHandle->data[1] = a->handle()->data[1] + 1;
427
428 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
429 // the native_handle when it goes out of scope
430 *aPlusOne = NativeHandle::create(rawHandle, true);
431 return NO_ERROR;
432 }
increment(const NoCopyNoMove & a,NoCopyNoMove * aPlusOne) const433 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
434 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
435 aPlusOne->setValue(a.getValue() + 1);
436 return NO_ERROR;
437 }
increment(const std::vector<TestParcelable> & a,std::vector<TestParcelable> * aPlusOne) const438 status_t increment(const std::vector<TestParcelable>& a,
439 std::vector<TestParcelable>* aPlusOne) const override {
440 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
441 aPlusOne->resize(a.size());
442 for (size_t i = 0; i < a.size(); ++i) {
443 (*aPlusOne)[i].setValue(a[i].getValue() + 1);
444 }
445 return NO_ERROR;
446 }
toUpper(const String8 & str,String8 * upperStr) const447 status_t toUpper(const String8& str, String8* upperStr) const override {
448 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
449 *upperStr = str;
450 upperStr->toUpper();
451 return NO_ERROR;
452 }
callMeBack(const sp<ICallback> & callback,int32_t a) const453 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
454 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
455 callback->onCallback(a + 1);
456 }
increment(int32_t a,int32_t * aPlusOne) const457 status_t increment(int32_t a, int32_t* aPlusOne) const override {
458 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
459 *aPlusOne = a + 1;
460 return NO_ERROR;
461 }
increment(uint32_t a,uint32_t * aPlusOne) const462 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
463 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
464 *aPlusOne = a + 1;
465 return NO_ERROR;
466 }
increment(int64_t a,int64_t * aPlusOne) const467 status_t increment(int64_t a, int64_t* aPlusOne) const override {
468 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
469 *aPlusOne = a + 1;
470 return NO_ERROR;
471 }
increment(uint64_t a,uint64_t * aPlusOne) const472 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
473 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
474 *aPlusOne = a + 1;
475 return NO_ERROR;
476 }
increment(int32_t a,int32_t * aPlusOne,int32_t b,int32_t * bPlusOne) const477 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
478 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
479 *aPlusOne = a + 1;
480 *bPlusOne = b + 1;
481 return NO_ERROR;
482 }
483
484 // BnInterface
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)485 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
486 uint32_t /*flags*/) override {
487 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
488 EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
489 ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
490 switch (tag) {
491 case ISafeInterfaceTest::Tag::SetDeathToken: {
492 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
493 }
494 case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
495 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
496 }
497 case ISafeInterfaceTest::Tag::LogicalNot: {
498 return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
499 }
500 case ISafeInterfaceTest::Tag::ModifyEnum: {
501 return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum);
502 }
503 case ISafeInterfaceTest::Tag::IncrementFlattenable: {
504 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
505 TestFlattenable* aPlusOne) const;
506 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
507 }
508 case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
509 using Signature =
510 status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
511 TestLightFlattenable* aPlusOne) const;
512 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
513 }
514 case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
515 using Signature =
516 status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
517 sp<TestLightRefBaseFlattenable>*) const;
518 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
519 }
520 case ISafeInterfaceTest::Tag::IncrementNativeHandle: {
521 using Signature = status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&,
522 sp<NativeHandle>*) const;
523 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
524 }
525 case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
526 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
527 NoCopyNoMove* aPlusOne) const;
528 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
529 }
530 case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
531 using Signature =
532 status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
533 std::vector<TestParcelable>*) const;
534 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
535 }
536 case ISafeInterfaceTest::Tag::ToUpper: {
537 return callLocal(data, reply, &ISafeInterfaceTest::toUpper);
538 }
539 case ISafeInterfaceTest::Tag::CallMeBack: {
540 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
541 }
542 case ISafeInterfaceTest::Tag::IncrementInt32: {
543 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
544 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
545 }
546 case ISafeInterfaceTest::Tag::IncrementUint32: {
547 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
548 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
549 }
550 case ISafeInterfaceTest::Tag::IncrementInt64: {
551 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
552 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
553 }
554 case ISafeInterfaceTest::Tag::IncrementUint64: {
555 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
556 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
557 }
558 case ISafeInterfaceTest::Tag::IncrementTwo: {
559 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
560 int32_t*) const;
561 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
562 }
563 case ISafeInterfaceTest::Tag::Last:
564 // Should not be possible because of the asserts at the beginning of the method
565 [&]() { FAIL(); }();
566 return UNKNOWN_ERROR;
567 }
568 }
569
570 private:
getLogTag()571 static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
572 };
573
574 class SafeInterfaceTest : public ::testing::Test {
575 public:
SafeInterfaceTest()576 SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
577 ProcessState::self()->startThreadPool();
578 }
579 ~SafeInterfaceTest() override = default;
580
581 protected:
582 sp<ISafeInterfaceTest> mSafeInterfaceTest;
583
584 private:
getLogTag()585 static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
586
getRemoteService()587 sp<ISafeInterfaceTest> getRemoteService() {
588 #pragma clang diagnostic push
589 #pragma clang diagnostic ignored "-Wexit-time-destructors"
590 static std::mutex sMutex;
591 static sp<ISafeInterfaceTest> sService;
592 static sp<IBinder> sDeathToken = new BBinder;
593 #pragma clang diagnostic pop
594
595 std::unique_lock<decltype(sMutex)> lock;
596 if (sService == nullptr) {
597 ALOG(LOG_INFO, getLogTag(), "Forking remote process");
598 pid_t forkPid = fork();
599 EXPECT_NE(forkPid, -1);
600
601 const String16 serviceName("SafeInterfaceTest");
602
603 if (forkPid == 0) {
604 ALOG(LOG_INFO, getLogTag(), "Remote process checking in");
605 sp<ISafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
606 defaultServiceManager()->addService(serviceName,
607 IInterface::asBinder(nativeService));
608 ProcessState::self()->startThreadPool();
609 IPCThreadState::self()->joinThreadPool();
610 // We shouldn't get to this point
611 [&]() { FAIL(); }();
612 }
613
614 sp<IBinder> binder = defaultServiceManager()->getService(serviceName);
615 sService = interface_cast<ISafeInterfaceTest>(binder);
616 EXPECT_TRUE(sService != nullptr);
617
618 sService->setDeathToken(sDeathToken);
619 }
620
621 return sService;
622 }
623 };
624
TEST_F(SafeInterfaceTest,TestReturnsNoMemory)625 TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
626 status_t result = mSafeInterfaceTest->returnsNoMemory();
627 ASSERT_EQ(NO_MEMORY, result);
628 }
629
TEST_F(SafeInterfaceTest,TestLogicalNot)630 TEST_F(SafeInterfaceTest, TestLogicalNot) {
631 const bool a = true;
632 bool notA = true;
633 status_t result = mSafeInterfaceTest->logicalNot(a, ¬A);
634 ASSERT_EQ(NO_ERROR, result);
635 ASSERT_EQ(!a, notA);
636 // Test both since we don't want to accidentally catch a default false somewhere
637 const bool b = false;
638 bool notB = false;
639 result = mSafeInterfaceTest->logicalNot(b, ¬B);
640 ASSERT_EQ(NO_ERROR, result);
641 ASSERT_EQ(!b, notB);
642 }
643
TEST_F(SafeInterfaceTest,TestModifyEnum)644 TEST_F(SafeInterfaceTest, TestModifyEnum) {
645 const TestEnum a = TestEnum::INITIAL;
646 TestEnum b = TestEnum::INVALID;
647 status_t result = mSafeInterfaceTest->modifyEnum(a, &b);
648 ASSERT_EQ(NO_ERROR, result);
649 ASSERT_EQ(TestEnum::FINAL, b);
650 }
651
TEST_F(SafeInterfaceTest,TestIncrementFlattenable)652 TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
653 const TestFlattenable a{1};
654 TestFlattenable 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
TEST_F(SafeInterfaceTest,TestIncrementLightFlattenable)660 TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
661 const TestLightFlattenable a{1};
662 TestLightFlattenable aPlusOne{0};
663 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
664 ASSERT_EQ(NO_ERROR, result);
665 ASSERT_EQ(a.value + 1, aPlusOne.value);
666 }
667
TEST_F(SafeInterfaceTest,TestIncrementLightRefBaseFlattenable)668 TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
669 sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
670 sp<TestLightRefBaseFlattenable> aPlusOne;
671 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
672 ASSERT_EQ(NO_ERROR, result);
673 ASSERT_NE(nullptr, aPlusOne.get());
674 ASSERT_EQ(a->value + 1, aPlusOne->value);
675 }
676
677 namespace { // Anonymous namespace
678
fdsAreEquivalent(int a,int b)679 bool fdsAreEquivalent(int a, int b) {
680 struct stat statA {};
681 struct stat statB {};
682 if (fstat(a, &statA) != 0) return false;
683 if (fstat(b, &statB) != 0) return false;
684 return (statA.st_dev == statB.st_dev) && (statA.st_ino == statB.st_ino);
685 }
686
687 } // Anonymous namespace
688
TEST_F(SafeInterfaceTest,TestIncrementNativeHandle)689 TEST_F(SafeInterfaceTest, TestIncrementNativeHandle) {
690 // Create an fd we can use to send and receive from the remote process
691 base::unique_fd eventFd{eventfd(0 /*initval*/, 0 /*flags*/)};
692 ASSERT_NE(-1, eventFd);
693
694 // Determine the maximum number of fds this process can have open
695 struct rlimit limit {};
696 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &limit));
697 uint32_t maxFds = static_cast<uint32_t>(limit.rlim_cur);
698
699 // Perform this test enough times to rule out fd leaks
700 for (uint32_t iter = 0; iter < (2 * maxFds); ++iter) {
701 native_handle* handle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
702 ASSERT_NE(nullptr, handle);
703 handle->data[0] = dup(eventFd.get());
704 handle->data[1] = 1;
705
706 // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
707 // the native_handle when it goes out of scope
708 sp<NativeHandle> a = NativeHandle::create(handle, true);
709
710 sp<NativeHandle> aPlusOne;
711 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
712 ASSERT_EQ(NO_ERROR, result);
713 ASSERT_TRUE(fdsAreEquivalent(a->handle()->data[0], aPlusOne->handle()->data[0]));
714 ASSERT_EQ(a->handle()->data[1] + 1, aPlusOne->handle()->data[1]);
715 }
716 }
717
TEST_F(SafeInterfaceTest,TestIncrementNoCopyNoMove)718 TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
719 const NoCopyNoMove a{1};
720 NoCopyNoMove aPlusOne{0};
721 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
722 ASSERT_EQ(NO_ERROR, result);
723 ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
724 }
725
TEST_F(SafeInterfaceTest,TestIncremementParcelableVector)726 TEST_F(SafeInterfaceTest, TestIncremementParcelableVector) {
727 const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
728 std::vector<TestParcelable> aPlusOne;
729 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
730 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
TEST_F(SafeInterfaceTest,TestToUpper)736 TEST_F(SafeInterfaceTest, TestToUpper) {
737 const String8 str{"Hello, world!"};
738 String8 upperStr;
739 status_t result = mSafeInterfaceTest->toUpper(str, &upperStr);
740 ASSERT_EQ(NO_ERROR, result);
741 ASSERT_TRUE(upperStr == String8{"HELLO, WORLD!"});
742 }
743
TEST_F(SafeInterfaceTest,TestCallMeBack)744 TEST_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
TEST_F(SafeInterfaceTest,TestIncrementInt32)775 TEST_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
TEST_F(SafeInterfaceTest,TestIncrementUint32)783 TEST_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
TEST_F(SafeInterfaceTest,TestIncrementInt64)791 TEST_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
TEST_F(SafeInterfaceTest,TestIncrementUint64)799 TEST_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
TEST_F(SafeInterfaceTest,TestIncrementTwo)807 TEST_F(SafeInterfaceTest, TestIncrementTwo) {
808 const int32_t a = 1;
809 int32_t aPlusOne = 0;
810 const int32_t b = 2;
811 int32_t bPlusOne = 0;
812 status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
813 ASSERT_EQ(NO_ERROR, result);
814 ASSERT_EQ(a + 1, aPlusOne);
815 ASSERT_EQ(b + 1, bPlusOne);
816 }
817
818 } // namespace tests
819 } // namespace android
820