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