blob: 70f49000f19b0b7df424219f65689f563c326c82 [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>
32
Dan Stozad630e522016-12-01 15:16:31 -080033#include <optional>
34
35using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
36
37namespace android {
38namespace tests {
39
40// This class serves two purposes:
41// 1) It ensures that the implementation doesn't require copying or moving the data (for
42// efficiency purposes)
43// 2) It tests that Parcelables can be passed correctly
44class NoCopyNoMove : public Parcelable {
45public:
46 NoCopyNoMove() = default;
47 explicit NoCopyNoMove(int32_t value) : mValue(value) {}
48 ~NoCopyNoMove() override = default;
49
50 // Not copyable
51 NoCopyNoMove(const NoCopyNoMove&) = delete;
52 NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
53
54 // Not movable
55 NoCopyNoMove(NoCopyNoMove&&) = delete;
56 NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
57
58 // Parcelable interface
59 status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
60 status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
61
62 int32_t getValue() const { return mValue; }
63 void setValue(int32_t value) { mValue = value; }
64
65private:
66 int32_t mValue = 0;
67 uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
68};
69
Dan Stozadf614ae2017-03-28 17:02:05 -070070struct TestFlattenable : Flattenable<TestFlattenable> {
71 TestFlattenable() = default;
72 explicit TestFlattenable(int32_t v) : value(v) {}
73
74 // Flattenable protocol
75 size_t getFlattenedSize() const { return sizeof(value); }
76 size_t getFdCount() const { return 0; }
77 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
78 FlattenableUtils::write(buffer, size, value);
79 return NO_ERROR;
80 }
81 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
82 FlattenableUtils::read(buffer, size, value);
83 return NO_ERROR;
84 }
85
86 int32_t value = 0;
87};
88
Dan Stozad630e522016-12-01 15:16:31 -080089struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
90 TestLightFlattenable() = default;
91 explicit TestLightFlattenable(int32_t v) : value(v) {}
92 int32_t value = 0;
93};
94
Dan Stoza6dd325b2017-04-07 14:31:51 -070095// It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
96// but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
97// base class
98class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
99 public LightRefBase<TestLightRefBaseFlattenable> {
100public:
101 TestLightRefBaseFlattenable() = default;
102 explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
103
104 // Flattenable protocol
105 size_t getFlattenedSize() const { return sizeof(value); }
106 size_t getFdCount() const { return 0; }
107 status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
108 FlattenableUtils::write(buffer, size, value);
109 return NO_ERROR;
110 }
111 status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
112 FlattenableUtils::read(buffer, size, value);
113 return NO_ERROR;
114 }
115
116 int32_t value = 0;
117};
118
Dan Stozad630e522016-12-01 15:16:31 -0800119class ExitOnDeath : public IBinder::DeathRecipient {
120public:
121 ~ExitOnDeath() override = default;
122
123 void binderDied(const wp<IBinder>& /*who*/) override {
124 ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
125 exit(0);
126 }
127};
128
129// This callback class is used to test both one-way transactions and that sp<IInterface> can be
130// passed correctly
131class ICallback : public IInterface {
132public:
133 DECLARE_META_INTERFACE(Callback)
134
135 enum class Tag : uint32_t {
136 OnCallback = IBinder::FIRST_CALL_TRANSACTION,
137 Last,
138 };
139
140 virtual void onCallback(int32_t aPlusOne) = 0;
141};
142
143class BpCallback : public SafeBpInterface<ICallback> {
144public:
145 explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
146
147 void onCallback(int32_t aPlusOne) override {
148 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
149 return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
150 }
151
152private:
153 static constexpr const char* getLogTag() { return "BpCallback"; }
154};
155
156#pragma clang diagnostic push
157#pragma clang diagnostic ignored "-Wexit-time-destructors"
158IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback");
159#pragma clang diagnostic pop
160
161class BnCallback : public SafeBnInterface<ICallback> {
162public:
163 BnCallback() : SafeBnInterface("BnCallback") {}
164
165 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
166 uint32_t /*flags*/) override {
167 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
168 EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
169 ICallback::Tag tag = static_cast<ICallback::Tag>(code);
170 switch (tag) {
171 case ICallback::Tag::OnCallback: {
172 return callLocalAsync(data, reply, &ICallback::onCallback);
173 }
174 case ICallback::Tag::Last:
175 // Should not be possible because of the asserts at the beginning of the method
176 [&]() { FAIL(); }();
177 return UNKNOWN_ERROR;
178 }
179 }
180};
181
182class ISafeInterfaceTest : public IInterface {
183public:
184 DECLARE_META_INTERFACE(SafeInterfaceTest)
185
186 enum class Tag : uint32_t {
187 SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
188 ReturnsNoMemory,
189 LogicalNot,
Dan Stozadf614ae2017-03-28 17:02:05 -0700190 IncrementFlattenable,
Dan Stozad630e522016-12-01 15:16:31 -0800191 IncrementLightFlattenable,
Dan Stoza6dd325b2017-04-07 14:31:51 -0700192 IncrementLightRefBaseFlattenable,
Dan Stozad630e522016-12-01 15:16:31 -0800193 IncrementNoCopyNoMove,
194 ToUpper,
195 CallMeBack,
196 IncrementInt32,
197 IncrementUint32,
Dan Stoza662a8992017-04-06 16:18:39 -0700198 IncrementInt64,
199 IncrementUint64,
Dan Stozad630e522016-12-01 15:16:31 -0800200 IncrementTwo,
201 Last,
202 };
203
204 // This is primarily so that the remote service dies when the test does, but it also serves to
205 // test the handling of sp<IBinder> and non-const methods
206 virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
207
208 // This is the most basic test since it doesn't require parceling any arguments
209 virtual status_t returnsNoMemory() const = 0;
210
211 // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
212 virtual status_t logicalNot(bool a, bool* notA) const = 0;
Dan Stozadf614ae2017-03-28 17:02:05 -0700213 virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800214 virtual status_t increment(const TestLightFlattenable& a,
215 TestLightFlattenable* aPlusOne) const = 0;
Dan Stoza6dd325b2017-04-07 14:31:51 -0700216 virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
217 sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800218 virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
219 virtual status_t toUpper(const String8& str, String8* upperStr) const = 0;
220 // As mentioned above, sp<IBinder> is already tested by setDeathToken
221 virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
222 virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
223 virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
Dan Stoza662a8992017-04-06 16:18:39 -0700224 virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
225 virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
Dan Stozad630e522016-12-01 15:16:31 -0800226
227 // This tests that input/output parameter interleaving works correctly
228 virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
229 int32_t* bPlusOne) const = 0;
230};
231
232class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
233public:
234 explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
235 : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
236
237 status_t setDeathToken(const sp<IBinder>& token) override {
238 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
239 return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
240 }
241 status_t returnsNoMemory() const override {
242 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
243 return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
244 }
245 status_t logicalNot(bool a, bool* notA) const override {
246 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
247 return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
248 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700249 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
250 using Signature =
251 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
252 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
253 return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
254 }
Dan Stozad630e522016-12-01 15:16:31 -0800255 status_t increment(const TestLightFlattenable& a,
256 TestLightFlattenable* aPlusOne) const override {
257 using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
258 TestLightFlattenable*) const;
259 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
260 return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
261 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700262 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
263 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
264 using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
265 sp<TestLightRefBaseFlattenable>*) const;
266 return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
267 }
Dan Stozad630e522016-12-01 15:16:31 -0800268 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
269 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
270 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
271 NoCopyNoMove* aPlusOne) const;
272 return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
273 }
274 status_t toUpper(const String8& str, String8* upperStr) const override {
275 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
276 return callRemote<decltype(&ISafeInterfaceTest::toUpper)>(Tag::ToUpper, str, upperStr);
277 }
278 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
279 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
280 return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
281 a);
282 }
283 status_t increment(int32_t a, int32_t* aPlusOne) const override {
284 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
285 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
286 return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
287 }
288 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
289 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
290 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
291 return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
292 }
Dan Stoza662a8992017-04-06 16:18:39 -0700293 status_t increment(int64_t a, int64_t* aPlusOne) const override {
294 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
295 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
296 return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
297 }
298 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
299 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
300 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
301 return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
302 }
Dan Stozad630e522016-12-01 15:16:31 -0800303 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
304 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
305 using Signature =
306 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
307 return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
308 }
309
310private:
311 static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
312};
313
314#pragma clang diagnostic push
315#pragma clang diagnostic ignored "-Wexit-time-destructors"
316IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest");
317
318static sp<IBinder::DeathRecipient> getDeathRecipient() {
319 static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
320 return recipient;
321}
322#pragma clang diagnostic pop
323
324class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
325public:
326 BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
327
328 status_t setDeathToken(const sp<IBinder>& token) override {
329 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
330 token->linkToDeath(getDeathRecipient());
331 return NO_ERROR;
332 }
333 status_t returnsNoMemory() const override {
334 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
335 return NO_MEMORY;
336 }
337 status_t logicalNot(bool a, bool* notA) const override {
338 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
339 *notA = !a;
340 return NO_ERROR;
341 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700342 status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
343 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
344 aPlusOne->value = a.value + 1;
345 return NO_ERROR;
346 }
Dan Stozad630e522016-12-01 15:16:31 -0800347 status_t increment(const TestLightFlattenable& a,
348 TestLightFlattenable* aPlusOne) const override {
349 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
350 aPlusOne->value = a.value + 1;
351 return NO_ERROR;
352 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700353 status_t increment(const sp<TestLightRefBaseFlattenable>& a,
354 sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
355 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
356 *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
357 return NO_ERROR;
358 }
Dan Stozad630e522016-12-01 15:16:31 -0800359 status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
360 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
361 aPlusOne->setValue(a.getValue() + 1);
362 return NO_ERROR;
363 }
364 status_t toUpper(const String8& str, String8* upperStr) const override {
365 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
366 *upperStr = str;
367 upperStr->toUpper();
368 return NO_ERROR;
369 }
370 void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
371 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
372 callback->onCallback(a + 1);
373 }
374 status_t increment(int32_t a, int32_t* aPlusOne) const override {
375 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
376 *aPlusOne = a + 1;
377 return NO_ERROR;
378 }
379 status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
380 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
381 *aPlusOne = a + 1;
382 return NO_ERROR;
383 }
Dan Stoza662a8992017-04-06 16:18:39 -0700384 status_t increment(int64_t a, int64_t* aPlusOne) const override {
385 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
386 *aPlusOne = a + 1;
387 return NO_ERROR;
388 }
389 status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
390 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
391 *aPlusOne = a + 1;
392 return NO_ERROR;
393 }
Dan Stozad630e522016-12-01 15:16:31 -0800394 status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
395 ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
396 *aPlusOne = a + 1;
397 *bPlusOne = b + 1;
398 return NO_ERROR;
399 }
400
401 // BnInterface
402 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
403 uint32_t /*flags*/) override {
404 EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
405 EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
406 ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
407 switch (tag) {
408 case ISafeInterfaceTest::Tag::SetDeathToken: {
409 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
410 }
411 case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
412 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
413 }
414 case ISafeInterfaceTest::Tag::LogicalNot: {
415 return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
416 }
Dan Stozadf614ae2017-03-28 17:02:05 -0700417 case ISafeInterfaceTest::Tag::IncrementFlattenable: {
418 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
419 TestFlattenable* aPlusOne) const;
420 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
421 }
Dan Stozad630e522016-12-01 15:16:31 -0800422 case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
423 using Signature =
424 status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
425 TestLightFlattenable* aPlusOne) const;
426 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
427 }
Dan Stoza6dd325b2017-04-07 14:31:51 -0700428 case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
429 using Signature =
430 status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
431 sp<TestLightRefBaseFlattenable>*) const;
432 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
433 }
Dan Stozad630e522016-12-01 15:16:31 -0800434 case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
435 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
436 NoCopyNoMove* aPlusOne) const;
437 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
438 }
439 case ISafeInterfaceTest::Tag::ToUpper: {
440 return callLocal(data, reply, &ISafeInterfaceTest::toUpper);
441 }
442 case ISafeInterfaceTest::Tag::CallMeBack: {
443 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
444 }
445 case ISafeInterfaceTest::Tag::IncrementInt32: {
446 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
447 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
448 }
449 case ISafeInterfaceTest::Tag::IncrementUint32: {
450 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
451 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
452 }
Dan Stoza662a8992017-04-06 16:18:39 -0700453 case ISafeInterfaceTest::Tag::IncrementInt64: {
454 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
455 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
456 }
457 case ISafeInterfaceTest::Tag::IncrementUint64: {
458 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
459 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
460 }
Dan Stozad630e522016-12-01 15:16:31 -0800461 case ISafeInterfaceTest::Tag::IncrementTwo: {
462 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
463 int32_t*) const;
464 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
465 }
466 case ISafeInterfaceTest::Tag::Last:
467 // Should not be possible because of the asserts at the beginning of the method
468 [&]() { FAIL(); }();
469 return UNKNOWN_ERROR;
470 }
471 }
472
473private:
474 static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
475};
476
477class SafeInterfaceTest : public ::testing::Test {
478public:
479 SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
480 ProcessState::self()->startThreadPool();
481 }
482 ~SafeInterfaceTest() override = default;
483
484protected:
485 sp<ISafeInterfaceTest> mSafeInterfaceTest;
486
487private:
488 static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
489
490 sp<ISafeInterfaceTest> getRemoteService() {
491#pragma clang diagnostic push
492#pragma clang diagnostic ignored "-Wexit-time-destructors"
493 static std::mutex sMutex;
494 static sp<ISafeInterfaceTest> sService;
495 static sp<IBinder> sDeathToken = new BBinder;
496#pragma clang diagnostic pop
497
498 std::unique_lock<decltype(sMutex)> lock;
499 if (sService == nullptr) {
500 ALOG(LOG_INFO, getLogTag(), "Forking remote process");
501 pid_t forkPid = fork();
502 EXPECT_NE(forkPid, -1);
503
504 const String16 serviceName("SafeInterfaceTest");
505
506 if (forkPid == 0) {
507 ALOG(LOG_INFO, getLogTag(), "Remote process checking in");
508 sp<ISafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
509 defaultServiceManager()->addService(serviceName,
510 IInterface::asBinder(nativeService));
511 ProcessState::self()->startThreadPool();
512 IPCThreadState::self()->joinThreadPool();
513 // We shouldn't get to this point
514 [&]() { FAIL(); }();
515 }
516
517 sp<IBinder> binder = defaultServiceManager()->getService(serviceName);
518 sService = interface_cast<ISafeInterfaceTest>(binder);
519 EXPECT_TRUE(sService != nullptr);
520
521 sService->setDeathToken(sDeathToken);
522 }
523
524 return sService;
525 }
526};
527
528TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
529 status_t result = mSafeInterfaceTest->returnsNoMemory();
530 ASSERT_EQ(NO_MEMORY, result);
531}
532
533TEST_F(SafeInterfaceTest, TestLogicalNot) {
534 const bool a = true;
535 bool notA = true;
536 status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
537 ASSERT_EQ(NO_ERROR, result);
538 ASSERT_EQ(!a, notA);
539 // Test both since we don't want to accidentally catch a default false somewhere
540 const bool b = false;
541 bool notB = false;
542 result = mSafeInterfaceTest->logicalNot(b, &notB);
543 ASSERT_EQ(NO_ERROR, result);
544 ASSERT_EQ(!b, notB);
545}
546
Dan Stozadf614ae2017-03-28 17:02:05 -0700547TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
548 const TestFlattenable a{1};
549 TestFlattenable aPlusOne{0};
550 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
551 ASSERT_EQ(NO_ERROR, result);
552 ASSERT_EQ(a.value + 1, aPlusOne.value);
553}
554
Dan Stozad630e522016-12-01 15:16:31 -0800555TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
556 const TestLightFlattenable a{1};
557 TestLightFlattenable aPlusOne{0};
558 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
559 ASSERT_EQ(NO_ERROR, result);
560 ASSERT_EQ(a.value + 1, aPlusOne.value);
561}
562
Dan Stoza6dd325b2017-04-07 14:31:51 -0700563TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
564 sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
565 sp<TestLightRefBaseFlattenable> aPlusOne;
566 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
567 ASSERT_EQ(NO_ERROR, result);
568 ASSERT_NE(nullptr, aPlusOne.get());
569 ASSERT_EQ(a->value + 1, aPlusOne->value);
570}
571
Dan Stozad630e522016-12-01 15:16:31 -0800572TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
573 const NoCopyNoMove a{1};
574 NoCopyNoMove aPlusOne{0};
575 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
576 ASSERT_EQ(NO_ERROR, result);
577 ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
578}
579
580TEST_F(SafeInterfaceTest, TestToUpper) {
581 const String8 str{"Hello, world!"};
582 String8 upperStr;
583 status_t result = mSafeInterfaceTest->toUpper(str, &upperStr);
584 ASSERT_EQ(NO_ERROR, result);
585 ASSERT_TRUE(upperStr == String8{"HELLO, WORLD!"});
586}
587
588TEST_F(SafeInterfaceTest, TestCallMeBack) {
589 class CallbackReceiver : public BnCallback {
590 public:
591 void onCallback(int32_t aPlusOne) override {
592 ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
593 std::unique_lock<decltype(mMutex)> lock(mMutex);
594 mValue = aPlusOne;
595 mCondition.notify_one();
596 }
597
598 std::optional<int32_t> waitForCallback() {
599 std::unique_lock<decltype(mMutex)> lock(mMutex);
600 bool success =
601 mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
602 return success ? mValue : std::nullopt;
603 }
604
605 private:
606 std::mutex mMutex;
607 std::condition_variable mCondition;
608 std::optional<int32_t> mValue;
609 };
610
611 sp<CallbackReceiver> receiver = new CallbackReceiver;
612 const int32_t a = 1;
613 mSafeInterfaceTest->callMeBack(receiver, a);
614 auto result = receiver->waitForCallback();
615 ASSERT_TRUE(result);
616 ASSERT_EQ(a + 1, *result);
617}
618
619TEST_F(SafeInterfaceTest, TestIncrementInt32) {
620 const int32_t a = 1;
621 int32_t aPlusOne = 0;
622 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
623 ASSERT_EQ(NO_ERROR, result);
624 ASSERT_EQ(a + 1, aPlusOne);
625}
626
627TEST_F(SafeInterfaceTest, TestIncrementUint32) {
628 const uint32_t a = 1;
629 uint32_t aPlusOne = 0;
630 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
631 ASSERT_EQ(NO_ERROR, result);
632 ASSERT_EQ(a + 1, aPlusOne);
633}
634
Dan Stoza662a8992017-04-06 16:18:39 -0700635TEST_F(SafeInterfaceTest, TestIncrementInt64) {
636 const int64_t a = 1;
637 int64_t aPlusOne = 0;
638 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
639 ASSERT_EQ(NO_ERROR, result);
640 ASSERT_EQ(a + 1, aPlusOne);
641}
642
643TEST_F(SafeInterfaceTest, TestIncrementUint64) {
644 const uint64_t a = 1;
645 uint64_t aPlusOne = 0;
646 status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
647 ASSERT_EQ(NO_ERROR, result);
648 ASSERT_EQ(a + 1, aPlusOne);
649}
650
Dan Stozad630e522016-12-01 15:16:31 -0800651TEST_F(SafeInterfaceTest, TestIncrementTwo) {
652 const int32_t a = 1;
653 int32_t aPlusOne = 0;
654 const int32_t b = 2;
655 int32_t bPlusOne = 0;
656 status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
657 ASSERT_EQ(NO_ERROR, result);
658 ASSERT_EQ(a + 1, aPlusOne);
659 ASSERT_EQ(b + 1, bPlusOne);
660}
661
662} // namespace tests
663} // namespace android