xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderSafeInterfaceTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2016 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <binder/SafeInterface.h>
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <binder/IInterface.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcelable.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
27*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Weverything"
28*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
29*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker #include <utils/Flattenable.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <utils/LightRefBase.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <utils/NativeHandle.h>
34*38e8c45fSAndroid Build Coastguard Worker 
35*38e8c45fSAndroid Build Coastguard Worker #include <cutils/native_handle.h>
36*38e8c45fSAndroid Build Coastguard Worker 
37*38e8c45fSAndroid Build Coastguard Worker #include <optional>
38*38e8c45fSAndroid Build Coastguard Worker 
39*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
40*38e8c45fSAndroid Build Coastguard Worker #include <sys/eventfd.h>
41*38e8c45fSAndroid Build Coastguard Worker #include <sys/prctl.h>
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker #include <gmock/gmock.h>
44*38e8c45fSAndroid Build Coastguard Worker 
45*38e8c45fSAndroid Build Coastguard Worker using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
46*38e8c45fSAndroid Build Coastguard Worker using android::binder::unique_fd;
47*38e8c45fSAndroid Build Coastguard Worker 
48*38e8c45fSAndroid Build Coastguard Worker namespace android {
49*38e8c45fSAndroid Build Coastguard Worker namespace tests {
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker static const String16 kServiceName("SafeInterfaceTest");
52*38e8c45fSAndroid Build Coastguard Worker 
53*38e8c45fSAndroid Build Coastguard Worker enum class TestEnum : uint32_t {
54*38e8c45fSAndroid Build Coastguard Worker     INVALID = 0,
55*38e8c45fSAndroid Build Coastguard Worker     INITIAL = 1,
56*38e8c45fSAndroid Build Coastguard Worker     FINAL = 2,
57*38e8c45fSAndroid Build Coastguard Worker };
58*38e8c45fSAndroid Build Coastguard Worker 
59*38e8c45fSAndroid Build Coastguard Worker // This class serves two purposes:
60*38e8c45fSAndroid Build Coastguard Worker //   1) It ensures that the implementation doesn't require copying or moving the data (for
61*38e8c45fSAndroid Build Coastguard Worker //      efficiency purposes)
62*38e8c45fSAndroid Build Coastguard Worker //   2) It tests that Parcelables can be passed correctly
63*38e8c45fSAndroid Build Coastguard Worker class NoCopyNoMove : public Parcelable {
64*38e8c45fSAndroid Build Coastguard Worker public:
65*38e8c45fSAndroid Build Coastguard Worker     NoCopyNoMove() = default;
NoCopyNoMove(int32_t value)66*38e8c45fSAndroid Build Coastguard Worker     explicit NoCopyNoMove(int32_t value) : mValue(value) {}
67*38e8c45fSAndroid Build Coastguard Worker     ~NoCopyNoMove() override = default;
68*38e8c45fSAndroid Build Coastguard Worker 
69*38e8c45fSAndroid Build Coastguard Worker     // Not copyable
70*38e8c45fSAndroid Build Coastguard Worker     NoCopyNoMove(const NoCopyNoMove&) = delete;
71*38e8c45fSAndroid Build Coastguard Worker     NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
72*38e8c45fSAndroid Build Coastguard Worker 
73*38e8c45fSAndroid Build Coastguard Worker     // Not movable
74*38e8c45fSAndroid Build Coastguard Worker     NoCopyNoMove(NoCopyNoMove&&) = delete;
75*38e8c45fSAndroid Build Coastguard Worker     NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
76*38e8c45fSAndroid Build Coastguard Worker 
77*38e8c45fSAndroid Build Coastguard Worker     // Parcelable interface
writeToParcel(Parcel * parcel) const78*38e8c45fSAndroid Build Coastguard Worker     status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
readFromParcel(const Parcel * parcel)79*38e8c45fSAndroid Build Coastguard Worker     status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
80*38e8c45fSAndroid Build Coastguard Worker 
getValue() const81*38e8c45fSAndroid Build Coastguard Worker     int32_t getValue() const { return mValue; }
setValue(int32_t value)82*38e8c45fSAndroid Build Coastguard Worker     void setValue(int32_t value) { mValue = value; }
83*38e8c45fSAndroid Build Coastguard Worker 
84*38e8c45fSAndroid Build Coastguard Worker private:
85*38e8c45fSAndroid Build Coastguard Worker     int32_t mValue = 0;
86*38e8c45fSAndroid Build Coastguard Worker     __attribute__((unused)) uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
87*38e8c45fSAndroid Build Coastguard Worker };
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker struct TestFlattenable : Flattenable<TestFlattenable> {
90*38e8c45fSAndroid Build Coastguard Worker     TestFlattenable() = default;
TestFlattenableandroid::tests::TestFlattenable91*38e8c45fSAndroid Build Coastguard Worker     explicit TestFlattenable(int32_t v) : value(v) {}
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     // Flattenable protocol
getFlattenedSizeandroid::tests::TestFlattenable94*38e8c45fSAndroid Build Coastguard Worker     size_t getFlattenedSize() const { return sizeof(value); }
getFdCountandroid::tests::TestFlattenable95*38e8c45fSAndroid Build Coastguard Worker     size_t getFdCount() const { return 0; }
flattenandroid::tests::TestFlattenable96*38e8c45fSAndroid Build Coastguard Worker     status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
97*38e8c45fSAndroid Build Coastguard Worker         FlattenableUtils::write(buffer, size, value);
98*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
99*38e8c45fSAndroid Build Coastguard Worker     }
unflattenandroid::tests::TestFlattenable100*38e8c45fSAndroid Build Coastguard Worker     status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
101*38e8c45fSAndroid Build Coastguard Worker         FlattenableUtils::read(buffer, size, value);
102*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
103*38e8c45fSAndroid Build Coastguard Worker     }
104*38e8c45fSAndroid Build Coastguard Worker 
105*38e8c45fSAndroid Build Coastguard Worker     int32_t value = 0;
106*38e8c45fSAndroid Build Coastguard Worker };
107*38e8c45fSAndroid Build Coastguard Worker 
108*38e8c45fSAndroid Build Coastguard Worker struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
109*38e8c45fSAndroid Build Coastguard Worker     TestLightFlattenable() = default;
TestLightFlattenableandroid::tests::TestLightFlattenable110*38e8c45fSAndroid Build Coastguard Worker     explicit TestLightFlattenable(int32_t v) : value(v) {}
111*38e8c45fSAndroid Build Coastguard Worker     int32_t value = 0;
112*38e8c45fSAndroid Build Coastguard Worker };
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker // It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
115*38e8c45fSAndroid Build Coastguard Worker // but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
116*38e8c45fSAndroid Build Coastguard Worker // base class
117*38e8c45fSAndroid Build Coastguard Worker class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
118*38e8c45fSAndroid Build Coastguard Worker                                     public LightRefBase<TestLightRefBaseFlattenable> {
119*38e8c45fSAndroid Build Coastguard Worker public:
120*38e8c45fSAndroid Build Coastguard Worker     TestLightRefBaseFlattenable() = default;
TestLightRefBaseFlattenable(int32_t v)121*38e8c45fSAndroid Build Coastguard Worker     explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker     // Flattenable protocol
getFlattenedSize() const124*38e8c45fSAndroid Build Coastguard Worker     size_t getFlattenedSize() const { return sizeof(value); }
getFdCount() const125*38e8c45fSAndroid Build Coastguard Worker     size_t getFdCount() const { return 0; }
flatten(void * & buffer,size_t & size,int * &,size_t &) const126*38e8c45fSAndroid Build Coastguard Worker     status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
127*38e8c45fSAndroid Build Coastguard Worker         FlattenableUtils::write(buffer, size, value);
128*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
129*38e8c45fSAndroid Build Coastguard Worker     }
unflatten(void const * & buffer,size_t & size,int const * &,size_t &)130*38e8c45fSAndroid Build Coastguard Worker     status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
131*38e8c45fSAndroid Build Coastguard Worker         FlattenableUtils::read(buffer, size, value);
132*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
133*38e8c45fSAndroid Build Coastguard Worker     }
134*38e8c45fSAndroid Build Coastguard Worker 
135*38e8c45fSAndroid Build Coastguard Worker     int32_t value = 0;
136*38e8c45fSAndroid Build Coastguard Worker };
137*38e8c45fSAndroid Build Coastguard Worker 
138*38e8c45fSAndroid Build Coastguard Worker class TestParcelable : public Parcelable {
139*38e8c45fSAndroid Build Coastguard Worker public:
140*38e8c45fSAndroid Build Coastguard Worker     TestParcelable() = default;
TestParcelable(int32_t value)141*38e8c45fSAndroid Build Coastguard Worker     explicit TestParcelable(int32_t value) : mValue(value) {}
TestParcelable(const TestParcelable & other)142*38e8c45fSAndroid Build Coastguard Worker     TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
TestParcelable(TestParcelable && other)143*38e8c45fSAndroid Build Coastguard Worker     TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
144*38e8c45fSAndroid Build Coastguard Worker 
145*38e8c45fSAndroid Build Coastguard Worker     // Parcelable interface
writeToParcel(Parcel * parcel) const146*38e8c45fSAndroid Build Coastguard Worker     status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
readFromParcel(const Parcel * parcel)147*38e8c45fSAndroid Build Coastguard Worker     status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
148*38e8c45fSAndroid Build Coastguard Worker 
getValue() const149*38e8c45fSAndroid Build Coastguard Worker     int32_t getValue() const { return mValue; }
setValue(int32_t value)150*38e8c45fSAndroid Build Coastguard Worker     void setValue(int32_t value) { mValue = value; }
151*38e8c45fSAndroid Build Coastguard Worker 
152*38e8c45fSAndroid Build Coastguard Worker private:
153*38e8c45fSAndroid Build Coastguard Worker     int32_t mValue = 0;
154*38e8c45fSAndroid Build Coastguard Worker };
155*38e8c45fSAndroid Build Coastguard Worker 
156*38e8c45fSAndroid Build Coastguard Worker class ExitOnDeath : public IBinder::DeathRecipient {
157*38e8c45fSAndroid Build Coastguard Worker public:
158*38e8c45fSAndroid Build Coastguard Worker     ~ExitOnDeath() override = default;
159*38e8c45fSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> &)160*38e8c45fSAndroid Build Coastguard Worker     void binderDied(const wp<IBinder>& /*who*/) override {
161*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
162*38e8c45fSAndroid Build Coastguard Worker         exit(0);
163*38e8c45fSAndroid Build Coastguard Worker     }
164*38e8c45fSAndroid Build Coastguard Worker };
165*38e8c45fSAndroid Build Coastguard Worker 
166*38e8c45fSAndroid Build Coastguard Worker // This callback class is used to test both one-way transactions and that sp<IInterface> can be
167*38e8c45fSAndroid Build Coastguard Worker // passed correctly
168*38e8c45fSAndroid Build Coastguard Worker class ICallback : public IInterface {
169*38e8c45fSAndroid Build Coastguard Worker public:
170*38e8c45fSAndroid Build Coastguard Worker     DECLARE_META_INTERFACE(Callback)
171*38e8c45fSAndroid Build Coastguard Worker 
172*38e8c45fSAndroid Build Coastguard Worker     enum class Tag : uint32_t {
173*38e8c45fSAndroid Build Coastguard Worker         OnCallback = IBinder::FIRST_CALL_TRANSACTION,
174*38e8c45fSAndroid Build Coastguard Worker         Last,
175*38e8c45fSAndroid Build Coastguard Worker     };
176*38e8c45fSAndroid Build Coastguard Worker 
177*38e8c45fSAndroid Build Coastguard Worker     virtual void onCallback(int32_t aPlusOne) = 0;
178*38e8c45fSAndroid Build Coastguard Worker };
179*38e8c45fSAndroid Build Coastguard Worker 
180*38e8c45fSAndroid Build Coastguard Worker class BpCallback : public SafeBpInterface<ICallback> {
181*38e8c45fSAndroid Build Coastguard Worker public:
BpCallback(const sp<IBinder> & impl)182*38e8c45fSAndroid Build Coastguard Worker     explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
183*38e8c45fSAndroid Build Coastguard Worker 
onCallback(int32_t aPlusOne)184*38e8c45fSAndroid Build Coastguard Worker     void onCallback(int32_t aPlusOne) override {
185*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
186*38e8c45fSAndroid Build Coastguard Worker         return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
187*38e8c45fSAndroid Build Coastguard Worker     }
188*38e8c45fSAndroid Build Coastguard Worker 
189*38e8c45fSAndroid Build Coastguard Worker private:
getLogTag()190*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* getLogTag() { return "BpCallback"; }
191*38e8c45fSAndroid Build Coastguard Worker };
192*38e8c45fSAndroid Build Coastguard Worker 
193*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
194*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wexit-time-destructors"
195*38e8c45fSAndroid Build Coastguard Worker IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback")
196*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
197*38e8c45fSAndroid Build Coastguard Worker 
198*38e8c45fSAndroid Build Coastguard Worker class BnCallback : public SafeBnInterface<ICallback> {
199*38e8c45fSAndroid Build Coastguard Worker public:
BnCallback()200*38e8c45fSAndroid Build Coastguard Worker     BnCallback() : SafeBnInterface("BnCallback") {}
201*38e8c45fSAndroid Build Coastguard Worker 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)202*38e8c45fSAndroid Build Coastguard Worker     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
203*38e8c45fSAndroid Build Coastguard Worker                         uint32_t /*flags*/) override {
204*38e8c45fSAndroid Build Coastguard Worker         EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
205*38e8c45fSAndroid Build Coastguard Worker         EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
206*38e8c45fSAndroid Build Coastguard Worker         ICallback::Tag tag = static_cast<ICallback::Tag>(code);
207*38e8c45fSAndroid Build Coastguard Worker         switch (tag) {
208*38e8c45fSAndroid Build Coastguard Worker             case ICallback::Tag::OnCallback: {
209*38e8c45fSAndroid Build Coastguard Worker                 return callLocalAsync(data, reply, &ICallback::onCallback);
210*38e8c45fSAndroid Build Coastguard Worker             }
211*38e8c45fSAndroid Build Coastguard Worker             case ICallback::Tag::Last:
212*38e8c45fSAndroid Build Coastguard Worker                 // Should not be possible because of the asserts at the beginning of the method
213*38e8c45fSAndroid Build Coastguard Worker                 [&]() { FAIL(); }();
214*38e8c45fSAndroid Build Coastguard Worker                 return UNKNOWN_ERROR;
215*38e8c45fSAndroid Build Coastguard Worker         }
216*38e8c45fSAndroid Build Coastguard Worker     }
217*38e8c45fSAndroid Build Coastguard Worker };
218*38e8c45fSAndroid Build Coastguard Worker 
219*38e8c45fSAndroid Build Coastguard Worker class ISafeInterfaceTest : public IInterface {
220*38e8c45fSAndroid Build Coastguard Worker public:
221*38e8c45fSAndroid Build Coastguard Worker     DECLARE_META_INTERFACE(SafeInterfaceTest)
222*38e8c45fSAndroid Build Coastguard Worker 
223*38e8c45fSAndroid Build Coastguard Worker     enum class Tag : uint32_t {
224*38e8c45fSAndroid Build Coastguard Worker         SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
225*38e8c45fSAndroid Build Coastguard Worker         ReturnsNoMemory,
226*38e8c45fSAndroid Build Coastguard Worker         LogicalNot,
227*38e8c45fSAndroid Build Coastguard Worker         LogicalNotVector,
228*38e8c45fSAndroid Build Coastguard Worker         ModifyEnum,
229*38e8c45fSAndroid Build Coastguard Worker         IncrementFlattenable,
230*38e8c45fSAndroid Build Coastguard Worker         IncrementLightFlattenable,
231*38e8c45fSAndroid Build Coastguard Worker         IncrementLightRefBaseFlattenable,
232*38e8c45fSAndroid Build Coastguard Worker         IncrementNativeHandle,
233*38e8c45fSAndroid Build Coastguard Worker         IncrementNoCopyNoMove,
234*38e8c45fSAndroid Build Coastguard Worker         IncrementParcelableVector,
235*38e8c45fSAndroid Build Coastguard Worker         DoubleString,
236*38e8c45fSAndroid Build Coastguard Worker         CallMeBack,
237*38e8c45fSAndroid Build Coastguard Worker         IncrementInt32,
238*38e8c45fSAndroid Build Coastguard Worker         IncrementUint32,
239*38e8c45fSAndroid Build Coastguard Worker         IncrementInt64,
240*38e8c45fSAndroid Build Coastguard Worker         IncrementUint64,
241*38e8c45fSAndroid Build Coastguard Worker         IncrementFloat,
242*38e8c45fSAndroid Build Coastguard Worker         IncrementTwo,
243*38e8c45fSAndroid Build Coastguard Worker         Last,
244*38e8c45fSAndroid Build Coastguard Worker     };
245*38e8c45fSAndroid Build Coastguard Worker 
246*38e8c45fSAndroid Build Coastguard Worker     // This is primarily so that the remote service dies when the test does, but it also serves to
247*38e8c45fSAndroid Build Coastguard Worker     // test the handling of sp<IBinder> and non-const methods
248*38e8c45fSAndroid Build Coastguard Worker     virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
249*38e8c45fSAndroid Build Coastguard Worker 
250*38e8c45fSAndroid Build Coastguard Worker     // This is the most basic test since it doesn't require parceling any arguments
251*38e8c45fSAndroid Build Coastguard Worker     virtual status_t returnsNoMemory() const = 0;
252*38e8c45fSAndroid Build Coastguard Worker 
253*38e8c45fSAndroid Build Coastguard Worker     // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
254*38e8c45fSAndroid Build Coastguard Worker     virtual status_t logicalNot(bool a, bool* notA) const = 0;
255*38e8c45fSAndroid Build Coastguard Worker     virtual status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const = 0;
256*38e8c45fSAndroid Build Coastguard Worker     virtual status_t modifyEnum(TestEnum a, TestEnum* b) const = 0;
257*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
258*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(const TestLightFlattenable& a,
259*38e8c45fSAndroid Build Coastguard Worker                                TestLightFlattenable* aPlusOne) const = 0;
260*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
261*38e8c45fSAndroid Build Coastguard Worker                                sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
262*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
263*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
264*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(const std::vector<TestParcelable>& a,
265*38e8c45fSAndroid Build Coastguard Worker                                std::vector<TestParcelable>* aPlusOne) const = 0;
266*38e8c45fSAndroid Build Coastguard Worker     virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
267*38e8c45fSAndroid Build Coastguard Worker     // As mentioned above, sp<IBinder> is already tested by setDeathToken
268*38e8c45fSAndroid Build Coastguard Worker     virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
269*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
270*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
271*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
272*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
273*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(float a, float* aPlusOne) const = 0;
274*38e8c45fSAndroid Build Coastguard Worker 
275*38e8c45fSAndroid Build Coastguard Worker     // This tests that input/output parameter interleaving works correctly
276*38e8c45fSAndroid Build Coastguard Worker     virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
277*38e8c45fSAndroid Build Coastguard Worker                                int32_t* bPlusOne) const = 0;
278*38e8c45fSAndroid Build Coastguard Worker };
279*38e8c45fSAndroid Build Coastguard Worker 
280*38e8c45fSAndroid Build Coastguard Worker class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
281*38e8c45fSAndroid Build Coastguard Worker public:
BpSafeInterfaceTest(const sp<IBinder> & impl)282*38e8c45fSAndroid Build Coastguard Worker     explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
283*38e8c45fSAndroid Build Coastguard Worker           : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
284*38e8c45fSAndroid Build Coastguard Worker 
setDeathToken(const sp<IBinder> & token)285*38e8c45fSAndroid Build Coastguard Worker     status_t setDeathToken(const sp<IBinder>& token) override {
286*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
287*38e8c45fSAndroid Build Coastguard Worker         return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
288*38e8c45fSAndroid Build Coastguard Worker     }
returnsNoMemory() const289*38e8c45fSAndroid Build Coastguard Worker     status_t returnsNoMemory() const override {
290*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
291*38e8c45fSAndroid Build Coastguard Worker         return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
292*38e8c45fSAndroid Build Coastguard Worker     }
logicalNot(bool a,bool * notA) const293*38e8c45fSAndroid Build Coastguard Worker     status_t logicalNot(bool a, bool* notA) const override {
294*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
295*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(bool, bool*) const;
296*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::LogicalNot, a, notA);
297*38e8c45fSAndroid Build Coastguard Worker     }
logicalNot(const std::vector<bool> & a,std::vector<bool> * notA) const298*38e8c45fSAndroid Build Coastguard Worker     status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override {
299*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
300*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>&,
301*38e8c45fSAndroid Build Coastguard Worker                                                            std::vector<bool>*) const;
302*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::LogicalNotVector, a, notA);
303*38e8c45fSAndroid Build Coastguard Worker     }
modifyEnum(TestEnum a,TestEnum * b) const304*38e8c45fSAndroid Build Coastguard Worker     status_t modifyEnum(TestEnum a, TestEnum* b) const override {
305*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
306*38e8c45fSAndroid Build Coastguard Worker         return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b);
307*38e8c45fSAndroid Build Coastguard Worker     }
increment(const TestFlattenable & a,TestFlattenable * aPlusOne) const308*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
309*38e8c45fSAndroid Build Coastguard Worker         using Signature =
310*38e8c45fSAndroid Build Coastguard Worker                 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
311*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
312*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
313*38e8c45fSAndroid Build Coastguard Worker     }
increment(const TestLightFlattenable & a,TestLightFlattenable * aPlusOne) const314*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const TestLightFlattenable& a,
315*38e8c45fSAndroid Build Coastguard Worker                        TestLightFlattenable* aPlusOne) const override {
316*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
317*38e8c45fSAndroid Build Coastguard Worker                                                            TestLightFlattenable*) const;
318*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
319*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
320*38e8c45fSAndroid Build Coastguard Worker     }
increment(const sp<TestLightRefBaseFlattenable> & a,sp<TestLightRefBaseFlattenable> * aPlusOne) const321*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const sp<TestLightRefBaseFlattenable>& a,
322*38e8c45fSAndroid Build Coastguard Worker                        sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
323*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
324*38e8c45fSAndroid Build Coastguard Worker                                                            sp<TestLightRefBaseFlattenable>*) const;
325*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
326*38e8c45fSAndroid Build Coastguard Worker     }
increment(const sp<NativeHandle> & a,sp<NativeHandle> * aPlusOne) const327*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
328*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
329*38e8c45fSAndroid Build Coastguard Worker         using Signature =
330*38e8c45fSAndroid Build Coastguard Worker                 status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&, sp<NativeHandle>*) const;
331*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementNativeHandle, a, aPlusOne);
332*38e8c45fSAndroid Build Coastguard Worker     }
increment(const NoCopyNoMove & a,NoCopyNoMove * aPlusOne) const333*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
334*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
335*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
336*38e8c45fSAndroid Build Coastguard Worker                                                            NoCopyNoMove* aPlusOne) const;
337*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
338*38e8c45fSAndroid Build Coastguard Worker     }
increment(const std::vector<TestParcelable> & a,std::vector<TestParcelable> * aPlusOne) const339*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const std::vector<TestParcelable>& a,
340*38e8c45fSAndroid Build Coastguard Worker                        std::vector<TestParcelable>* aPlusOne) const override {
341*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
342*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
343*38e8c45fSAndroid Build Coastguard Worker                                                            std::vector<TestParcelable>*);
344*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
345*38e8c45fSAndroid Build Coastguard Worker     }
doubleString(const String8 & str,String8 * doubleStr) const346*38e8c45fSAndroid Build Coastguard Worker     status_t doubleString(const String8& str, String8* doubleStr) const override {
347*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
348*38e8c45fSAndroid Build Coastguard Worker         return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
349*38e8c45fSAndroid Build Coastguard Worker                                                                        doubleStr);
350*38e8c45fSAndroid Build Coastguard Worker     }
callMeBack(const sp<ICallback> & callback,int32_t a) const351*38e8c45fSAndroid Build Coastguard Worker     void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
352*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
353*38e8c45fSAndroid Build Coastguard Worker         return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
354*38e8c45fSAndroid Build Coastguard Worker                                                                           a);
355*38e8c45fSAndroid Build Coastguard Worker     }
increment(int32_t a,int32_t * aPlusOne) const356*38e8c45fSAndroid Build Coastguard Worker     status_t increment(int32_t a, int32_t* aPlusOne) const override {
357*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
358*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
359*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
360*38e8c45fSAndroid Build Coastguard Worker     }
increment(uint32_t a,uint32_t * aPlusOne) const361*38e8c45fSAndroid Build Coastguard Worker     status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
362*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
363*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
364*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
365*38e8c45fSAndroid Build Coastguard Worker     }
increment(int64_t a,int64_t * aPlusOne) const366*38e8c45fSAndroid Build Coastguard Worker     status_t increment(int64_t a, int64_t* aPlusOne) const override {
367*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
368*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
369*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
370*38e8c45fSAndroid Build Coastguard Worker     }
increment(uint64_t a,uint64_t * aPlusOne) const371*38e8c45fSAndroid Build Coastguard Worker     status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
372*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
373*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
374*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
375*38e8c45fSAndroid Build Coastguard Worker     }
increment(float a,float * aPlusOne) const376*38e8c45fSAndroid Build Coastguard Worker     status_t increment(float a, float* aPlusOne) const override {
377*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
378*38e8c45fSAndroid Build Coastguard Worker         using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
379*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementFloat, a, aPlusOne);
380*38e8c45fSAndroid Build Coastguard Worker     }
increment(int32_t a,int32_t * aPlusOne,int32_t b,int32_t * bPlusOne) const381*38e8c45fSAndroid Build Coastguard Worker     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
382*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
383*38e8c45fSAndroid Build Coastguard Worker         using Signature =
384*38e8c45fSAndroid Build Coastguard Worker                 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
385*38e8c45fSAndroid Build Coastguard Worker         return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
386*38e8c45fSAndroid Build Coastguard Worker     }
387*38e8c45fSAndroid Build Coastguard Worker 
388*38e8c45fSAndroid Build Coastguard Worker private:
getLogTag()389*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
390*38e8c45fSAndroid Build Coastguard Worker };
391*38e8c45fSAndroid Build Coastguard Worker 
392*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
393*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wexit-time-destructors"
394*38e8c45fSAndroid Build Coastguard Worker IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest")
395*38e8c45fSAndroid Build Coastguard Worker 
getDeathRecipient()396*38e8c45fSAndroid Build Coastguard Worker static sp<IBinder::DeathRecipient> getDeathRecipient() {
397*38e8c45fSAndroid Build Coastguard Worker     static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
398*38e8c45fSAndroid Build Coastguard Worker     return recipient;
399*38e8c45fSAndroid Build Coastguard Worker }
400*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
401*38e8c45fSAndroid Build Coastguard Worker 
402*38e8c45fSAndroid Build Coastguard Worker class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
403*38e8c45fSAndroid Build Coastguard Worker public:
BnSafeInterfaceTest()404*38e8c45fSAndroid Build Coastguard Worker     BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
405*38e8c45fSAndroid Build Coastguard Worker 
setDeathToken(const sp<IBinder> & token)406*38e8c45fSAndroid Build Coastguard Worker     status_t setDeathToken(const sp<IBinder>& token) override {
407*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
408*38e8c45fSAndroid Build Coastguard Worker         token->linkToDeath(getDeathRecipient());
409*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
410*38e8c45fSAndroid Build Coastguard Worker     }
returnsNoMemory() const411*38e8c45fSAndroid Build Coastguard Worker     status_t returnsNoMemory() const override {
412*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
413*38e8c45fSAndroid Build Coastguard Worker         return NO_MEMORY;
414*38e8c45fSAndroid Build Coastguard Worker     }
logicalNot(bool a,bool * notA) const415*38e8c45fSAndroid Build Coastguard Worker     status_t logicalNot(bool a, bool* notA) const override {
416*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
417*38e8c45fSAndroid Build Coastguard Worker         *notA = !a;
418*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
419*38e8c45fSAndroid Build Coastguard Worker     }
logicalNot(const std::vector<bool> & a,std::vector<bool> * notA) const420*38e8c45fSAndroid Build Coastguard Worker     status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override {
421*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
422*38e8c45fSAndroid Build Coastguard Worker         notA->clear();
423*38e8c45fSAndroid Build Coastguard Worker         for (bool value : a) {
424*38e8c45fSAndroid Build Coastguard Worker             notA->push_back(!value);
425*38e8c45fSAndroid Build Coastguard Worker         }
426*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
427*38e8c45fSAndroid Build Coastguard Worker     }
modifyEnum(TestEnum a,TestEnum * b) const428*38e8c45fSAndroid Build Coastguard Worker     status_t modifyEnum(TestEnum a, TestEnum* b) const override {
429*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
430*38e8c45fSAndroid Build Coastguard Worker         *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID;
431*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
432*38e8c45fSAndroid Build Coastguard Worker     }
increment(const TestFlattenable & a,TestFlattenable * aPlusOne) const433*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
434*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
435*38e8c45fSAndroid Build Coastguard Worker         aPlusOne->value = a.value + 1;
436*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
437*38e8c45fSAndroid Build Coastguard Worker     }
increment(const TestLightFlattenable & a,TestLightFlattenable * aPlusOne) const438*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const TestLightFlattenable& a,
439*38e8c45fSAndroid Build Coastguard Worker                        TestLightFlattenable* aPlusOne) const override {
440*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
441*38e8c45fSAndroid Build Coastguard Worker         aPlusOne->value = a.value + 1;
442*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
443*38e8c45fSAndroid Build Coastguard Worker     }
increment(const sp<TestLightRefBaseFlattenable> & a,sp<TestLightRefBaseFlattenable> * aPlusOne) const444*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const sp<TestLightRefBaseFlattenable>& a,
445*38e8c45fSAndroid Build Coastguard Worker                        sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
446*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
447*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
448*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
449*38e8c45fSAndroid Build Coastguard Worker     }
increment(const sp<NativeHandle> & a,sp<NativeHandle> * aPlusOne) const450*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
451*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
452*38e8c45fSAndroid Build Coastguard Worker         native_handle* rawHandle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
453*38e8c45fSAndroid Build Coastguard Worker         if (rawHandle == nullptr) return NO_MEMORY;
454*38e8c45fSAndroid Build Coastguard Worker 
455*38e8c45fSAndroid Build Coastguard Worker         // Copy the fd over directly
456*38e8c45fSAndroid Build Coastguard Worker         rawHandle->data[0] = dup(a->handle()->data[0]);
457*38e8c45fSAndroid Build Coastguard Worker 
458*38e8c45fSAndroid Build Coastguard Worker         // Increment the int
459*38e8c45fSAndroid Build Coastguard Worker         rawHandle->data[1] = a->handle()->data[1] + 1;
460*38e8c45fSAndroid Build Coastguard Worker 
461*38e8c45fSAndroid Build Coastguard Worker         // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
462*38e8c45fSAndroid Build Coastguard Worker         // the native_handle when it goes out of scope
463*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = NativeHandle::create(rawHandle, true);
464*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
465*38e8c45fSAndroid Build Coastguard Worker     }
increment(const NoCopyNoMove & a,NoCopyNoMove * aPlusOne) const466*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
467*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
468*38e8c45fSAndroid Build Coastguard Worker         aPlusOne->setValue(a.getValue() + 1);
469*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
470*38e8c45fSAndroid Build Coastguard Worker     }
increment(const std::vector<TestParcelable> & a,std::vector<TestParcelable> * aPlusOne) const471*38e8c45fSAndroid Build Coastguard Worker     status_t increment(const std::vector<TestParcelable>& a,
472*38e8c45fSAndroid Build Coastguard Worker                        std::vector<TestParcelable>* aPlusOne) const override {
473*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
474*38e8c45fSAndroid Build Coastguard Worker         aPlusOne->resize(a.size());
475*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < a.size(); ++i) {
476*38e8c45fSAndroid Build Coastguard Worker             (*aPlusOne)[i].setValue(a[i].getValue() + 1);
477*38e8c45fSAndroid Build Coastguard Worker         }
478*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
479*38e8c45fSAndroid Build Coastguard Worker     }
doubleString(const String8 & str,String8 * doubleStr) const480*38e8c45fSAndroid Build Coastguard Worker     status_t doubleString(const String8& str, String8* doubleStr) const override {
481*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
482*38e8c45fSAndroid Build Coastguard Worker         *doubleStr = str + str;
483*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
484*38e8c45fSAndroid Build Coastguard Worker     }
callMeBack(const sp<ICallback> & callback,int32_t a) const485*38e8c45fSAndroid Build Coastguard Worker     void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
486*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
487*38e8c45fSAndroid Build Coastguard Worker         callback->onCallback(a + 1);
488*38e8c45fSAndroid Build Coastguard Worker     }
increment(int32_t a,int32_t * aPlusOne) const489*38e8c45fSAndroid Build Coastguard Worker     status_t increment(int32_t a, int32_t* aPlusOne) const override {
490*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
491*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = a + 1;
492*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
493*38e8c45fSAndroid Build Coastguard Worker     }
increment(uint32_t a,uint32_t * aPlusOne) const494*38e8c45fSAndroid Build Coastguard Worker     status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
495*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
496*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = a + 1;
497*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
498*38e8c45fSAndroid Build Coastguard Worker     }
increment(int64_t a,int64_t * aPlusOne) const499*38e8c45fSAndroid Build Coastguard Worker     status_t increment(int64_t a, int64_t* aPlusOne) const override {
500*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
501*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = a + 1;
502*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
503*38e8c45fSAndroid Build Coastguard Worker     }
increment(uint64_t a,uint64_t * aPlusOne) const504*38e8c45fSAndroid Build Coastguard Worker     status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
505*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
506*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = a + 1;
507*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
508*38e8c45fSAndroid Build Coastguard Worker     }
increment(float a,float * aPlusOne) const509*38e8c45fSAndroid Build Coastguard Worker     status_t increment(float a, float* aPlusOne) const override {
510*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
511*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = a + 1.0f;
512*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
513*38e8c45fSAndroid Build Coastguard Worker     }
increment(int32_t a,int32_t * aPlusOne,int32_t b,int32_t * bPlusOne) const514*38e8c45fSAndroid Build Coastguard Worker     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
515*38e8c45fSAndroid Build Coastguard Worker         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
516*38e8c45fSAndroid Build Coastguard Worker         *aPlusOne = a + 1;
517*38e8c45fSAndroid Build Coastguard Worker         *bPlusOne = b + 1;
518*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
519*38e8c45fSAndroid Build Coastguard Worker     }
520*38e8c45fSAndroid Build Coastguard Worker 
521*38e8c45fSAndroid Build Coastguard Worker     // BnInterface
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)522*38e8c45fSAndroid Build Coastguard Worker     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
523*38e8c45fSAndroid Build Coastguard Worker                         uint32_t /*flags*/) override {
524*38e8c45fSAndroid Build Coastguard Worker         EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
525*38e8c45fSAndroid Build Coastguard Worker         EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
526*38e8c45fSAndroid Build Coastguard Worker         ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
527*38e8c45fSAndroid Build Coastguard Worker         switch (tag) {
528*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::SetDeathToken: {
529*38e8c45fSAndroid Build Coastguard Worker                 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
530*38e8c45fSAndroid Build Coastguard Worker             }
531*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
532*38e8c45fSAndroid Build Coastguard Worker                 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
533*38e8c45fSAndroid Build Coastguard Worker             }
534*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::LogicalNot: {
535*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(bool a, bool* notA) const;
536*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot);
537*38e8c45fSAndroid Build Coastguard Worker             }
538*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::LogicalNotVector: {
539*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>& a,
540*38e8c45fSAndroid Build Coastguard Worker                                                                    std::vector<bool>* notA) const;
541*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot);
542*38e8c45fSAndroid Build Coastguard Worker             }
543*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::ModifyEnum: {
544*38e8c45fSAndroid Build Coastguard Worker                 return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum);
545*38e8c45fSAndroid Build Coastguard Worker             }
546*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementFlattenable: {
547*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
548*38e8c45fSAndroid Build Coastguard Worker                                                                    TestFlattenable* aPlusOne) const;
549*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
550*38e8c45fSAndroid Build Coastguard Worker             }
551*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
552*38e8c45fSAndroid Build Coastguard Worker                 using Signature =
553*38e8c45fSAndroid Build Coastguard Worker                         status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
554*38e8c45fSAndroid Build Coastguard Worker                                                          TestLightFlattenable* aPlusOne) const;
555*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
556*38e8c45fSAndroid Build Coastguard Worker             }
557*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
558*38e8c45fSAndroid Build Coastguard Worker                 using Signature =
559*38e8c45fSAndroid Build Coastguard Worker                         status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
560*38e8c45fSAndroid Build Coastguard Worker                                                          sp<TestLightRefBaseFlattenable>*) const;
561*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
562*38e8c45fSAndroid Build Coastguard Worker             }
563*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementNativeHandle: {
564*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&,
565*38e8c45fSAndroid Build Coastguard Worker                                                                    sp<NativeHandle>*) const;
566*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
567*38e8c45fSAndroid Build Coastguard Worker             }
568*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
569*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
570*38e8c45fSAndroid Build Coastguard Worker                                                                    NoCopyNoMove* aPlusOne) const;
571*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
572*38e8c45fSAndroid Build Coastguard Worker             }
573*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
574*38e8c45fSAndroid Build Coastguard Worker                 using Signature =
575*38e8c45fSAndroid Build Coastguard Worker                         status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
576*38e8c45fSAndroid Build Coastguard Worker                                                          std::vector<TestParcelable>*) const;
577*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
578*38e8c45fSAndroid Build Coastguard Worker             }
579*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::DoubleString: {
580*38e8c45fSAndroid Build Coastguard Worker                 return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
581*38e8c45fSAndroid Build Coastguard Worker             }
582*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::CallMeBack: {
583*38e8c45fSAndroid Build Coastguard Worker                 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
584*38e8c45fSAndroid Build Coastguard Worker             }
585*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementInt32: {
586*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
587*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
588*38e8c45fSAndroid Build Coastguard Worker             }
589*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementUint32: {
590*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
591*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
592*38e8c45fSAndroid Build Coastguard Worker             }
593*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementInt64: {
594*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
595*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
596*38e8c45fSAndroid Build Coastguard Worker             }
597*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementUint64: {
598*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
599*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
600*38e8c45fSAndroid Build Coastguard Worker             }
601*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementFloat: {
602*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
603*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
604*38e8c45fSAndroid Build Coastguard Worker             }
605*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::IncrementTwo: {
606*38e8c45fSAndroid Build Coastguard Worker                 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
607*38e8c45fSAndroid Build Coastguard Worker                                                                    int32_t*) const;
608*38e8c45fSAndroid Build Coastguard Worker                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
609*38e8c45fSAndroid Build Coastguard Worker             }
610*38e8c45fSAndroid Build Coastguard Worker             case ISafeInterfaceTest::Tag::Last:
611*38e8c45fSAndroid Build Coastguard Worker                 // Should not be possible because of the asserts at the beginning of the method
612*38e8c45fSAndroid Build Coastguard Worker                 [&]() { FAIL(); }();
613*38e8c45fSAndroid Build Coastguard Worker                 return UNKNOWN_ERROR;
614*38e8c45fSAndroid Build Coastguard Worker         }
615*38e8c45fSAndroid Build Coastguard Worker     }
616*38e8c45fSAndroid Build Coastguard Worker 
617*38e8c45fSAndroid Build Coastguard Worker private:
getLogTag()618*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
619*38e8c45fSAndroid Build Coastguard Worker };
620*38e8c45fSAndroid Build Coastguard Worker 
621*38e8c45fSAndroid Build Coastguard Worker class SafeInterfaceTest : public ::testing::Test {
622*38e8c45fSAndroid Build Coastguard Worker public:
SafeInterfaceTest()623*38e8c45fSAndroid Build Coastguard Worker     SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
624*38e8c45fSAndroid Build Coastguard Worker         ProcessState::self()->startThreadPool();
625*38e8c45fSAndroid Build Coastguard Worker     }
626*38e8c45fSAndroid Build Coastguard Worker     ~SafeInterfaceTest() override = default;
627*38e8c45fSAndroid Build Coastguard Worker 
628*38e8c45fSAndroid Build Coastguard Worker protected:
629*38e8c45fSAndroid Build Coastguard Worker     sp<ISafeInterfaceTest> mSafeInterfaceTest;
630*38e8c45fSAndroid Build Coastguard Worker 
631*38e8c45fSAndroid Build Coastguard Worker private:
getLogTag()632*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
633*38e8c45fSAndroid Build Coastguard Worker 
getRemoteService()634*38e8c45fSAndroid Build Coastguard Worker     sp<ISafeInterfaceTest> getRemoteService() {
635*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
636*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wdeprecated-declarations"
637*38e8c45fSAndroid Build Coastguard Worker         sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
638*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
639*38e8c45fSAndroid Build Coastguard Worker         sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
640*38e8c45fSAndroid Build Coastguard Worker         EXPECT_TRUE(iface != nullptr);
641*38e8c45fSAndroid Build Coastguard Worker 
642*38e8c45fSAndroid Build Coastguard Worker         iface->setDeathToken(new BBinder);
643*38e8c45fSAndroid Build Coastguard Worker 
644*38e8c45fSAndroid Build Coastguard Worker         return iface;
645*38e8c45fSAndroid Build Coastguard Worker     }
646*38e8c45fSAndroid Build Coastguard Worker };
647*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestReturnsNoMemory)648*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
649*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->returnsNoMemory();
650*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_MEMORY, result);
651*38e8c45fSAndroid Build Coastguard Worker }
652*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestLogicalNot)653*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestLogicalNot) {
654*38e8c45fSAndroid Build Coastguard Worker     const bool a = true;
655*38e8c45fSAndroid Build Coastguard Worker     bool notA = true;
656*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
657*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
658*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(!a, notA);
659*38e8c45fSAndroid Build Coastguard Worker     // Test both since we don't want to accidentally catch a default false somewhere
660*38e8c45fSAndroid Build Coastguard Worker     const bool b = false;
661*38e8c45fSAndroid Build Coastguard Worker     bool notB = false;
662*38e8c45fSAndroid Build Coastguard Worker     result = mSafeInterfaceTest->logicalNot(b, &notB);
663*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
664*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(!b, notB);
665*38e8c45fSAndroid Build Coastguard Worker }
666*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestLogicalNotVector)667*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestLogicalNotVector) {
668*38e8c45fSAndroid Build Coastguard Worker     const std::vector<bool> a = {true, false, true};
669*38e8c45fSAndroid Build Coastguard Worker     std::vector<bool> notA;
670*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
671*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
672*38e8c45fSAndroid Build Coastguard Worker     std::vector<bool> expected = {false, true, false};
673*38e8c45fSAndroid Build Coastguard Worker     ASSERT_THAT(notA, testing::ContainerEq(expected));
674*38e8c45fSAndroid Build Coastguard Worker }
675*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestModifyEnum)676*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestModifyEnum) {
677*38e8c45fSAndroid Build Coastguard Worker     const TestEnum a = TestEnum::INITIAL;
678*38e8c45fSAndroid Build Coastguard Worker     TestEnum b = TestEnum::INVALID;
679*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->modifyEnum(a, &b);
680*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
681*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(TestEnum::FINAL, b);
682*38e8c45fSAndroid Build Coastguard Worker }
683*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementFlattenable)684*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
685*38e8c45fSAndroid Build Coastguard Worker     const TestFlattenable a{1};
686*38e8c45fSAndroid Build Coastguard Worker     TestFlattenable aPlusOne{0};
687*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
688*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
689*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a.value + 1, aPlusOne.value);
690*38e8c45fSAndroid Build Coastguard Worker }
691*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementLightFlattenable)692*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
693*38e8c45fSAndroid Build Coastguard Worker     const TestLightFlattenable a{1};
694*38e8c45fSAndroid Build Coastguard Worker     TestLightFlattenable aPlusOne{0};
695*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
696*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
697*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a.value + 1, aPlusOne.value);
698*38e8c45fSAndroid Build Coastguard Worker }
699*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementLightRefBaseFlattenable)700*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
701*38e8c45fSAndroid Build Coastguard Worker     sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
702*38e8c45fSAndroid Build Coastguard Worker     sp<TestLightRefBaseFlattenable> aPlusOne;
703*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
704*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
705*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, aPlusOne.get());
706*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a->value + 1, aPlusOne->value);
707*38e8c45fSAndroid Build Coastguard Worker }
708*38e8c45fSAndroid Build Coastguard Worker 
709*38e8c45fSAndroid Build Coastguard Worker namespace { // Anonymous namespace
710*38e8c45fSAndroid Build Coastguard Worker 
fdsAreEquivalent(int a,int b)711*38e8c45fSAndroid Build Coastguard Worker bool fdsAreEquivalent(int a, int b) {
712*38e8c45fSAndroid Build Coastguard Worker     struct stat statA {};
713*38e8c45fSAndroid Build Coastguard Worker     struct stat statB {};
714*38e8c45fSAndroid Build Coastguard Worker     if (fstat(a, &statA) != 0) return false;
715*38e8c45fSAndroid Build Coastguard Worker     if (fstat(b, &statB) != 0) return false;
716*38e8c45fSAndroid Build Coastguard Worker     return (statA.st_dev == statB.st_dev) && (statA.st_ino == statB.st_ino);
717*38e8c45fSAndroid Build Coastguard Worker }
718*38e8c45fSAndroid Build Coastguard Worker 
719*38e8c45fSAndroid Build Coastguard Worker } // Anonymous namespace
720*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementNativeHandle)721*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementNativeHandle) {
722*38e8c45fSAndroid Build Coastguard Worker     // Create an fd we can use to send and receive from the remote process
723*38e8c45fSAndroid Build Coastguard Worker     unique_fd eventFd{eventfd(0 /*initval*/, 0 /*flags*/)};
724*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, eventFd);
725*38e8c45fSAndroid Build Coastguard Worker 
726*38e8c45fSAndroid Build Coastguard Worker     // Determine the maximum number of fds this process can have open
727*38e8c45fSAndroid Build Coastguard Worker     struct rlimit limit {};
728*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &limit));
729*38e8c45fSAndroid Build Coastguard Worker     uint64_t maxFds = limit.rlim_cur;
730*38e8c45fSAndroid Build Coastguard Worker 
731*38e8c45fSAndroid Build Coastguard Worker     ALOG(LOG_INFO, "SafeInterfaceTest", "%s max FDs: %" PRIu64, __PRETTY_FUNCTION__, maxFds);
732*38e8c45fSAndroid Build Coastguard Worker 
733*38e8c45fSAndroid Build Coastguard Worker     // Perform this test enough times to rule out fd leaks
734*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t iter = 0; iter < (maxFds + 100); ++iter) {
735*38e8c45fSAndroid Build Coastguard Worker         native_handle* handle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
736*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(nullptr, handle);
737*38e8c45fSAndroid Build Coastguard Worker         handle->data[0] = dup(eventFd.get());
738*38e8c45fSAndroid Build Coastguard Worker         handle->data[1] = 1;
739*38e8c45fSAndroid Build Coastguard Worker 
740*38e8c45fSAndroid Build Coastguard Worker         // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
741*38e8c45fSAndroid Build Coastguard Worker         // the native_handle when it goes out of scope
742*38e8c45fSAndroid Build Coastguard Worker         sp<NativeHandle> a = NativeHandle::create(handle, true);
743*38e8c45fSAndroid Build Coastguard Worker 
744*38e8c45fSAndroid Build Coastguard Worker         sp<NativeHandle> aPlusOne;
745*38e8c45fSAndroid Build Coastguard Worker         status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
746*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(NO_ERROR, result);
747*38e8c45fSAndroid Build Coastguard Worker         ASSERT_TRUE(fdsAreEquivalent(a->handle()->data[0], aPlusOne->handle()->data[0]));
748*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(a->handle()->data[1] + 1, aPlusOne->handle()->data[1]);
749*38e8c45fSAndroid Build Coastguard Worker     }
750*38e8c45fSAndroid Build Coastguard Worker }
751*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementNoCopyNoMove)752*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
753*38e8c45fSAndroid Build Coastguard Worker     const NoCopyNoMove a{1};
754*38e8c45fSAndroid Build Coastguard Worker     NoCopyNoMove aPlusOne{0};
755*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
756*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
757*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
758*38e8c45fSAndroid Build Coastguard Worker }
759*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementParcelableVector)760*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementParcelableVector) {
761*38e8c45fSAndroid Build Coastguard Worker     const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
762*38e8c45fSAndroid Build Coastguard Worker     std::vector<TestParcelable> aPlusOne;
763*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
764*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
765*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a.size(), aPlusOne.size());
766*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < a.size(); ++i) {
767*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(a[i].getValue() + 1, aPlusOne[i].getValue());
768*38e8c45fSAndroid Build Coastguard Worker     }
769*38e8c45fSAndroid Build Coastguard Worker }
770*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestDoubleString)771*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestDoubleString) {
772*38e8c45fSAndroid Build Coastguard Worker     const String8 str{"asdf"};
773*38e8c45fSAndroid Build Coastguard Worker     String8 doubleStr;
774*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
775*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
776*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
777*38e8c45fSAndroid Build Coastguard Worker }
778*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestCallMeBack)779*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestCallMeBack) {
780*38e8c45fSAndroid Build Coastguard Worker     class CallbackReceiver : public BnCallback {
781*38e8c45fSAndroid Build Coastguard Worker     public:
782*38e8c45fSAndroid Build Coastguard Worker         void onCallback(int32_t aPlusOne) override {
783*38e8c45fSAndroid Build Coastguard Worker             ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
784*38e8c45fSAndroid Build Coastguard Worker             std::unique_lock<decltype(mMutex)> lock(mMutex);
785*38e8c45fSAndroid Build Coastguard Worker             mValue = aPlusOne;
786*38e8c45fSAndroid Build Coastguard Worker             mCondition.notify_one();
787*38e8c45fSAndroid Build Coastguard Worker         }
788*38e8c45fSAndroid Build Coastguard Worker 
789*38e8c45fSAndroid Build Coastguard Worker         std::optional<int32_t> waitForCallback() {
790*38e8c45fSAndroid Build Coastguard Worker             std::unique_lock<decltype(mMutex)> lock(mMutex);
791*38e8c45fSAndroid Build Coastguard Worker             bool success =
792*38e8c45fSAndroid Build Coastguard Worker                     mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
793*38e8c45fSAndroid Build Coastguard Worker             return success ? mValue : std::nullopt;
794*38e8c45fSAndroid Build Coastguard Worker         }
795*38e8c45fSAndroid Build Coastguard Worker 
796*38e8c45fSAndroid Build Coastguard Worker     private:
797*38e8c45fSAndroid Build Coastguard Worker         std::mutex mMutex;
798*38e8c45fSAndroid Build Coastguard Worker         std::condition_variable mCondition;
799*38e8c45fSAndroid Build Coastguard Worker         std::optional<int32_t> mValue;
800*38e8c45fSAndroid Build Coastguard Worker     };
801*38e8c45fSAndroid Build Coastguard Worker 
802*38e8c45fSAndroid Build Coastguard Worker     sp<CallbackReceiver> receiver = new CallbackReceiver;
803*38e8c45fSAndroid Build Coastguard Worker     const int32_t a = 1;
804*38e8c45fSAndroid Build Coastguard Worker     mSafeInterfaceTest->callMeBack(receiver, a);
805*38e8c45fSAndroid Build Coastguard Worker     auto result = receiver->waitForCallback();
806*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(result);
807*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a + 1, *result);
808*38e8c45fSAndroid Build Coastguard Worker }
809*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementInt32)810*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementInt32) {
811*38e8c45fSAndroid Build Coastguard Worker     const int32_t a = 1;
812*38e8c45fSAndroid Build Coastguard Worker     int32_t aPlusOne = 0;
813*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
814*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
815*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a + 1, aPlusOne);
816*38e8c45fSAndroid Build Coastguard Worker }
817*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementUint32)818*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementUint32) {
819*38e8c45fSAndroid Build Coastguard Worker     const uint32_t a = 1;
820*38e8c45fSAndroid Build Coastguard Worker     uint32_t aPlusOne = 0;
821*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
822*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
823*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a + 1, aPlusOne);
824*38e8c45fSAndroid Build Coastguard Worker }
825*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementInt64)826*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementInt64) {
827*38e8c45fSAndroid Build Coastguard Worker     const int64_t a = 1;
828*38e8c45fSAndroid Build Coastguard Worker     int64_t aPlusOne = 0;
829*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
830*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
831*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a + 1, aPlusOne);
832*38e8c45fSAndroid Build Coastguard Worker }
833*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementUint64)834*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementUint64) {
835*38e8c45fSAndroid Build Coastguard Worker     const uint64_t a = 1;
836*38e8c45fSAndroid Build Coastguard Worker     uint64_t aPlusOne = 0;
837*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
838*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
839*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a + 1, aPlusOne);
840*38e8c45fSAndroid Build Coastguard Worker }
841*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementFloat)842*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementFloat) {
843*38e8c45fSAndroid Build Coastguard Worker     const float a = 1.0f;
844*38e8c45fSAndroid Build Coastguard Worker     float aPlusOne = 0.0f;
845*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
846*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
847*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a + 1.0f, aPlusOne);
848*38e8c45fSAndroid Build Coastguard Worker }
849*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(SafeInterfaceTest,TestIncrementTwo)850*38e8c45fSAndroid Build Coastguard Worker TEST_F(SafeInterfaceTest, TestIncrementTwo) {
851*38e8c45fSAndroid Build Coastguard Worker     const int32_t a = 1;
852*38e8c45fSAndroid Build Coastguard Worker     int32_t aPlusOne = 0;
853*38e8c45fSAndroid Build Coastguard Worker     const int32_t b = 2;
854*38e8c45fSAndroid Build Coastguard Worker     int32_t bPlusOne = 0;
855*38e8c45fSAndroid Build Coastguard Worker     status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
856*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, result);
857*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(a + 1, aPlusOne);
858*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(b + 1, bPlusOne);
859*38e8c45fSAndroid Build Coastguard Worker }
860*38e8c45fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)861*38e8c45fSAndroid Build Coastguard Worker extern "C" int main(int argc, char **argv) {
862*38e8c45fSAndroid Build Coastguard Worker     testing::InitGoogleTest(&argc, argv);
863*38e8c45fSAndroid Build Coastguard Worker 
864*38e8c45fSAndroid Build Coastguard Worker     if (fork() == 0) {
865*38e8c45fSAndroid Build Coastguard Worker         prctl(PR_SET_PDEATHSIG, SIGHUP);
866*38e8c45fSAndroid Build Coastguard Worker         sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
867*38e8c45fSAndroid Build Coastguard Worker         status_t status = defaultServiceManager()->addService(kServiceName, nativeService);
868*38e8c45fSAndroid Build Coastguard Worker         if (status != OK) {
869*38e8c45fSAndroid Build Coastguard Worker             ALOG(LOG_INFO, "SafeInterfaceServer", "could not register");
870*38e8c45fSAndroid Build Coastguard Worker             return EXIT_FAILURE;
871*38e8c45fSAndroid Build Coastguard Worker         }
872*38e8c45fSAndroid Build Coastguard Worker         IPCThreadState::self()->joinThreadPool();
873*38e8c45fSAndroid Build Coastguard Worker         return EXIT_FAILURE;
874*38e8c45fSAndroid Build Coastguard Worker     }
875*38e8c45fSAndroid Build Coastguard Worker 
876*38e8c45fSAndroid Build Coastguard Worker     return RUN_ALL_TESTS();
877*38e8c45fSAndroid Build Coastguard Worker }
878*38e8c45fSAndroid Build Coastguard Worker 
879*38e8c45fSAndroid Build Coastguard Worker } // namespace tests
880*38e8c45fSAndroid Build Coastguard Worker } // namespace android
881