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