| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 1 | #define LOG_TAG "hidl_test" | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 2 | #include <android-base/logging.h> | 
|  | 3 |  | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 4 | #include <android/hidl/manager/1.0/IServiceManager.h> | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 5 | #include <android/hidl/manager/1.0/IServiceNotification.h> | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 6 |  | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 7 | #include <android/hidl/memory/1.0/IAllocator.h> | 
|  | 8 | #include <android/hidl/memory/1.0/IMemory.h> | 
|  | 9 |  | 
| Steven Moreland | aa2b83a | 2016-12-21 15:52:11 -0800 | [diff] [blame] | 10 | #include <android/hidl/token/1.0/ITokenManager.h> | 
|  | 11 |  | 
| Steven Moreland | b48a7da | 2016-11-11 14:12:46 -0800 | [diff] [blame] | 12 | #include <android/hardware/tests/foo/1.0/IFoo.h> | 
|  | 13 | #include <android/hardware/tests/foo/1.0/IFooCallback.h> | 
| Yifan Hong | def2cfb | 2016-12-14 16:00:24 -0800 | [diff] [blame] | 14 | #include <android/hardware/tests/foo/1.0/BnSimple.h> | 
|  | 15 | // TODO(b/33669138): remove | 
|  | 16 | #include <cutils/trace.h> | 
|  | 17 | #include <android/hardware/tests/foo/1.0/BsSimple.h> | 
|  | 18 | #include <android/hardware/tests/foo/1.0/BpSimple.h> | 
|  | 19 |  | 
| Steven Moreland | b48a7da | 2016-11-11 14:12:46 -0800 | [diff] [blame] | 20 | #include <android/hardware/tests/bar/1.0/IBar.h> | 
| Yifan Hong | 5749b2c | 2016-11-28 12:52:36 -0800 | [diff] [blame] | 21 | #include <android/hardware/tests/bar/1.0/IComplicated.h> | 
| Steven Moreland | b48a7da | 2016-11-11 14:12:46 -0800 | [diff] [blame] | 22 | #include <android/hardware/tests/inheritance/1.0/IFetcher.h> | 
|  | 23 | #include <android/hardware/tests/inheritance/1.0/IGrandparent.h> | 
|  | 24 | #include <android/hardware/tests/inheritance/1.0/IParent.h> | 
|  | 25 | #include <android/hardware/tests/inheritance/1.0/IChild.h> | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 26 | #include <android/hardware/tests/memory/1.0/IMemoryTest.h> | 
| Steven Moreland | b48a7da | 2016-11-11 14:12:46 -0800 | [diff] [blame] | 27 | #include <android/hardware/tests/pointer/1.0/IGraph.h> | 
|  | 28 | #include <android/hardware/tests/pointer/1.0/IPointer.h> | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 29 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 30 | #include <gtest/gtest.h> | 
|  | 31 | #if GTEST_IS_THREADSAFE | 
|  | 32 | #include <sys/types.h> | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 33 | #include <sys/wait.h> | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 34 | #include <signal.h> | 
|  | 35 | #include <errno.h> | 
|  | 36 | #include <pthread.h> | 
|  | 37 | #else | 
|  | 38 | #error "GTest did not detect pthread library." | 
|  | 39 | #endif | 
|  | 40 |  | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 41 | #include <algorithm> | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 42 | #include <condition_variable> | 
| Yifan Hong | d12398d | 2016-10-13 11:05:29 -0700 | [diff] [blame] | 43 | #include <getopt.h> | 
|  | 44 | #include <inttypes.h> | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 45 | #include <mutex> | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 46 | #include <set> | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 47 | #include <sstream> | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 48 | #include <utility> | 
| Yifan Hong | d12398d | 2016-10-13 11:05:29 -0700 | [diff] [blame] | 49 | #include <vector> | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 50 |  | 
| Yifan Hong | 398e6fb | 2016-10-17 11:38:09 -0700 | [diff] [blame] | 51 | #include <hidl-test/FooHelper.h> | 
|  | 52 | #include <hidl-test/PointerHelper.h> | 
|  | 53 |  | 
| Martijn Coenen | 9391510 | 2016-09-01 01:35:52 +0200 | [diff] [blame] | 54 | #include <hidl/Status.h> | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 55 | #include <hidlmemory/mapping.h> | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 56 | #include <hwbinder/IPCThreadState.h> | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 57 | #include <hwbinder/ProcessState.h> | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 58 |  | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 59 | #include <utils/Condition.h> | 
|  | 60 | #include <utils/Timers.h> | 
|  | 61 |  | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 62 | #define EXPECT_OK(__ret__) EXPECT_TRUE(isOk(__ret__)) | 
| Yifan Hong | 8446590 | 2016-09-27 15:52:17 -0700 | [diff] [blame] | 63 | #define EXPECT_FAIL(__ret__) EXPECT_FALSE(isOk(__ret__)) | 
| Yifan Hong | 8c48ad7 | 2016-10-14 11:34:59 -0700 | [diff] [blame] | 64 | #define EXPECT_ARRAYEQ(__a1__, __a2__, __size__) EXPECT_TRUE(isArrayEqual(__a1__, __a2__, __size__)) | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 65 |  | 
|  | 66 | // TODO uncomment this when kernel is patched with pointer changes. | 
|  | 67 | //#define HIDL_RUN_POINTER_TESTS 1 | 
|  | 68 |  | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 69 | // forward declarations. | 
|  | 70 | class PassthroughEnvironment; | 
|  | 71 | class BinderizedEnvironment; | 
|  | 72 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 73 | // static storage | 
|  | 74 | static enum TestMode { | 
|  | 75 | BINDERIZED, | 
|  | 76 | PASSTHROUGH | 
|  | 77 | } gMode; | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 78 | static PassthroughEnvironment *gPassthroughEnvironment = nullptr; | 
|  | 79 | static BinderizedEnvironment *gBinderizedEnvironment = nullptr; | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 80 | // per process tag | 
|  | 81 | static std::string gServiceName; | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 82 | // end static storage | 
|  | 83 |  | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 84 | using ::android::hardware::tests::foo::V1_0::Abc; | 
| Steven Moreland | 88ca451 | 2016-08-11 11:24:10 -0700 | [diff] [blame] | 85 | using ::android::hardware::tests::foo::V1_0::IFoo; | 
|  | 86 | using ::android::hardware::tests::foo::V1_0::IFooCallback; | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 87 | using ::android::hardware::tests::foo::V1_0::ISimple; | 
| Steven Moreland | 88ca451 | 2016-08-11 11:24:10 -0700 | [diff] [blame] | 88 | using ::android::hardware::tests::bar::V1_0::IBar; | 
| Yifan Hong | 5749b2c | 2016-11-28 12:52:36 -0800 | [diff] [blame] | 89 | using ::android::hardware::tests::bar::V1_0::IComplicated; | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 90 | using ::android::hardware::tests::inheritance::V1_0::IFetcher; | 
|  | 91 | using ::android::hardware::tests::inheritance::V1_0::IGrandparent; | 
|  | 92 | using ::android::hardware::tests::inheritance::V1_0::IParent; | 
|  | 93 | using ::android::hardware::tests::inheritance::V1_0::IChild; | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 94 | using ::android::hardware::tests::pointer::V1_0::IGraph; | 
|  | 95 | using ::android::hardware::tests::pointer::V1_0::IPointer; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 96 | using ::android::hardware::tests::memory::V1_0::IMemoryTest; | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 97 | using ::android::hardware::IPCThreadState; | 
|  | 98 | using ::android::hardware::ProcessState; | 
| Iliyan Malchev | 2b6591b | 2016-08-18 19:15:19 -0700 | [diff] [blame] | 99 | using ::android::hardware::Return; | 
| Iliyan Malchev | d57066f | 2016-09-08 13:59:38 -0700 | [diff] [blame] | 100 | using ::android::hardware::Void; | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 101 | using ::android::hardware::hidl_array; | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 102 | using ::android::hardware::hidl_death_recipient; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 103 | using ::android::hardware::hidl_memory; | 
| Andreas Huber | 8a82ff7 | 2016-08-04 10:29:39 -0700 | [diff] [blame] | 104 | using ::android::hardware::hidl_string; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 105 | using ::android::hardware::hidl_vec; | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 106 | using ::android::hidl::base::V1_0::IBase; | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 107 | using ::android::hidl::manager::V1_0::IServiceManager; | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 108 | using ::android::hidl::manager::V1_0::IServiceNotification; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 109 | using ::android::hidl::memory::V1_0::IAllocator; | 
|  | 110 | using ::android::hidl::memory::V1_0::IMemory; | 
| Steven Moreland | aa2b83a | 2016-12-21 15:52:11 -0800 | [diff] [blame] | 111 | using ::android::hidl::token::V1_0::ITokenManager; | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 112 | using ::android::sp; | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 113 | using ::android::wp; | 
| Yifan Hong | 398e6fb | 2016-10-17 11:38:09 -0700 | [diff] [blame] | 114 | using ::android::to_string; | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 115 | using ::android::Mutex; | 
| Yifan Hong | 398e6fb | 2016-10-17 11:38:09 -0700 | [diff] [blame] | 116 | using ::android::MultiDimensionalToString; | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 117 | using ::android::Condition; | 
| Yifan Hong | 398e6fb | 2016-10-17 11:38:09 -0700 | [diff] [blame] | 118 | using ::android::DELAY_S; | 
|  | 119 | using ::android::DELAY_NS; | 
|  | 120 | using ::android::TOLERANCE_NS; | 
|  | 121 | using ::android::ONEWAY_TOLERANCE_NS; | 
|  | 122 | using std::to_string; | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 123 |  | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 124 | template <typename T> | 
|  | 125 | static inline ::testing::AssertionResult isOk(::android::hardware::Return<T> ret) { | 
|  | 126 | return ret.getStatus().isOk() | 
|  | 127 | ? (::testing::AssertionSuccess() << ret.getStatus()) | 
|  | 128 | : (::testing::AssertionFailure() << ret.getStatus()); | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | template<typename T, typename S> | 
|  | 132 | static inline bool isArrayEqual(const T arr1, const S arr2, size_t size) { | 
|  | 133 | for(size_t i = 0; i < size; i++) | 
|  | 134 | if(arr1[i] != arr2[i]) | 
|  | 135 | return false; | 
|  | 136 | return true; | 
|  | 137 | } | 
|  | 138 |  | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 139 | template<typename T> | 
|  | 140 | std::string to_string(std::set<T> set) { | 
|  | 141 | std::stringstream ss; | 
|  | 142 | ss << "{"; | 
|  | 143 |  | 
|  | 144 | bool first = true; | 
|  | 145 | for (const T &item : set) { | 
|  | 146 | if (first) { | 
|  | 147 | first = false; | 
|  | 148 | } else { | 
|  | 149 | ss << ", "; | 
|  | 150 | } | 
|  | 151 |  | 
|  | 152 | ss << to_string(item); | 
|  | 153 | } | 
|  | 154 |  | 
|  | 155 | ss << "}"; | 
|  | 156 |  | 
|  | 157 | return ss.str(); | 
|  | 158 | } | 
|  | 159 |  | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 160 | struct Simple : public ISimple { | 
|  | 161 | Simple(int32_t cookie) | 
|  | 162 | : mCookie(cookie) { | 
|  | 163 | } | 
|  | 164 |  | 
|  | 165 | Return<int32_t> getCookie() override { | 
|  | 166 | return mCookie; | 
|  | 167 | } | 
|  | 168 |  | 
| Yifan Hong | 5749b2c | 2016-11-28 12:52:36 -0800 | [diff] [blame] | 169 | Return<void> customVecInt(customVecInt_cb _cb) override { | 
|  | 170 | _cb(hidl_vec<int32_t>()); | 
|  | 171 | return Void(); | 
|  | 172 | } | 
|  | 173 |  | 
|  | 174 | Return<void> customVecStr(customVecStr_cb _cb) override { | 
|  | 175 | hidl_vec<hidl_string> vec; | 
|  | 176 | vec.resize(2); | 
|  | 177 | _cb(vec); | 
|  | 178 | return Void(); | 
|  | 179 | } | 
|  | 180 |  | 
|  | 181 | Return<void> mystr(mystr_cb _cb) override { | 
|  | 182 | _cb(hidl_string()); | 
|  | 183 | return Void(); | 
|  | 184 | } | 
|  | 185 |  | 
|  | 186 | Return<void> myhandle(myhandle_cb _cb) override { | 
|  | 187 | auto h = native_handle_create(0, 1); | 
|  | 188 | _cb(h); | 
|  | 189 | native_handle_delete(h); | 
|  | 190 | return Void(); | 
|  | 191 | } | 
|  | 192 |  | 
|  | 193 | private: | 
|  | 194 | int32_t mCookie; | 
|  | 195 | }; | 
|  | 196 |  | 
|  | 197 | struct Complicated : public IComplicated { | 
|  | 198 | Complicated(int32_t cookie) | 
|  | 199 | : mCookie(cookie) { | 
|  | 200 | } | 
|  | 201 |  | 
|  | 202 | Return<int32_t> getCookie() override { | 
|  | 203 | return mCookie; | 
|  | 204 | } | 
|  | 205 |  | 
|  | 206 | Return<void> customVecInt(customVecInt_cb _cb) override { | 
|  | 207 | _cb(hidl_vec<int32_t>()); | 
|  | 208 | return Void(); | 
|  | 209 | } | 
|  | 210 | Return<void> customVecStr(customVecStr_cb _cb) override { | 
|  | 211 | hidl_vec<hidl_string> vec; | 
|  | 212 | vec.resize(2); | 
|  | 213 | _cb(vec); | 
|  | 214 | return Void(); | 
|  | 215 | } | 
|  | 216 |  | 
|  | 217 | Return<void> mystr(mystr_cb _cb) override { | 
|  | 218 | _cb(hidl_string()); | 
|  | 219 | return Void(); | 
|  | 220 | } | 
|  | 221 |  | 
|  | 222 | Return<void> myhandle(myhandle_cb _cb) override { | 
|  | 223 | auto h = native_handle_create(0, 1); | 
|  | 224 | _cb(h); | 
|  | 225 | native_handle_delete(h); | 
|  | 226 | return Void(); | 
|  | 227 | } | 
|  | 228 |  | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 229 | private: | 
|  | 230 | int32_t mCookie; | 
|  | 231 | }; | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 232 |  | 
|  | 233 | struct ServiceNotification : public IServiceNotification { | 
|  | 234 | std::mutex mutex; | 
|  | 235 | std::condition_variable condition; | 
|  | 236 |  | 
|  | 237 | Return<void> onRegistration(const hidl_string &fqName, | 
|  | 238 | const hidl_string &name, | 
|  | 239 | bool preexisting) override { | 
|  | 240 | if (preexisting) { | 
|  | 241 | // not interested in things registered from previous runs of hidl_test | 
|  | 242 | return Void(); | 
|  | 243 | } | 
|  | 244 |  | 
|  | 245 | std::unique_lock<std::mutex> lock(mutex); | 
|  | 246 |  | 
|  | 247 | mRegistered.push_back(std::string(fqName.c_str()) + "/" + name.c_str()); | 
|  | 248 |  | 
|  | 249 | lock.unlock(); | 
|  | 250 | condition.notify_one(); | 
|  | 251 |  | 
|  | 252 | return Void(); | 
|  | 253 | } | 
|  | 254 |  | 
|  | 255 | const std::vector<std::string> &getRegistrations() const { | 
|  | 256 | return mRegistered; | 
|  | 257 | } | 
|  | 258 |  | 
|  | 259 | private: | 
|  | 260 | std::vector<std::string> mRegistered{}; | 
|  | 261 | }; | 
|  | 262 |  | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 263 | void signal_handler(int signal) | 
|  | 264 | { | 
|  | 265 | if (signal == SIGTERM) { | 
|  | 266 | ALOGD("SERVER %s shutting down...", gServiceName.c_str()); | 
|  | 267 | IPCThreadState::shutdown(); | 
|  | 268 | ALOGD("SERVER %s shutdown.", gServiceName.c_str()); | 
|  | 269 | exit(0); | 
|  | 270 | } | 
|  | 271 | } | 
|  | 272 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 273 | template <class T> | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 274 | static pid_t forkServer(const std::string &serviceName) { | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 275 | pid_t pid; | 
| Steven Moreland | c7167ca | 2016-11-28 11:29:55 -0800 | [diff] [blame] | 276 |  | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 277 | // use fork to create and kill to destroy server processes. | 
|  | 278 | // getStub = true to get the passthrough version as the backend for the | 
|  | 279 | // binderized service. | 
|  | 280 | if ((pid = fork()) == 0) { | 
|  | 281 | // in child process | 
|  | 282 | sp<T> server = T::getService(serviceName, true); | 
|  | 283 | gServiceName = serviceName; | 
|  | 284 | signal(SIGTERM, signal_handler); | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 285 | ALOGD("SERVER registering %s", serviceName.c_str()); | 
| Steven Moreland | c7167ca | 2016-11-28 11:29:55 -0800 | [diff] [blame] | 286 | ::android::status_t status = server->registerAsService(serviceName); | 
|  | 287 | if (status != ::android::OK) { | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 288 | ALOGE("SERVER could not register %s", serviceName.c_str()); | 
| Steven Moreland | c7167ca | 2016-11-28 11:29:55 -0800 | [diff] [blame] | 289 | exit(-1); | 
|  | 290 | } | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 291 | ALOGD("SERVER starting %s", serviceName.c_str()); | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 292 | ProcessState::self()->setThreadPoolMaxThreadCount(0); | 
|  | 293 | ProcessState::self()->startThreadPool(); | 
|  | 294 | IPCThreadState::self()->joinThreadPool(); | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 295 | ALOGD("SERVER %s ends.", serviceName.c_str()); | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 296 | exit(0); | 
|  | 297 | } | 
| Steven Moreland | c7167ca | 2016-11-28 11:29:55 -0800 | [diff] [blame] | 298 |  | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 299 | // in main process | 
|  | 300 | return pid; | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 301 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 302 |  | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 303 | static void killServer(pid_t pid, const char *serverName) { | 
|  | 304 | if(kill(pid, SIGTERM)) { | 
|  | 305 | ALOGE("Could not kill %s; errno = %d", serverName, errno); | 
|  | 306 | } else { | 
|  | 307 | int status; | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 308 | ALOGD("Waiting for %s to exit...", serverName); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 309 | waitpid(pid, &status, 0); | 
| Yifan Hong | 35d6600 | 2016-10-13 12:47:44 -0700 | [diff] [blame] | 310 | if (status != 0) { | 
|  | 311 | ALOGE("%s terminates abnormally with status %d", serverName, status); | 
|  | 312 | } | 
|  | 313 | ALOGD("Continuing..."); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 314 | } | 
|  | 315 | } | 
|  | 316 |  | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 317 | class HidlEnvironmentBase : public ::testing::Environment { | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 318 | protected: | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 319 | std::vector<std::pair<std::string, pid_t>> mPids; | 
|  | 320 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 321 | public: | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 322 | sp<IServiceManager> manager; | 
| Steven Moreland | aa2b83a | 2016-12-21 15:52:11 -0800 | [diff] [blame] | 323 | sp<ITokenManager> tokenManager; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 324 | sp<IAllocator> ashmemAllocator; | 
|  | 325 | sp<IMemoryTest> memoryTest; | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 326 | sp<IFetcher> fetcher; | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 327 | sp<IFoo> foo; | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 328 | sp<IFoo> dyingFoo; | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 329 | sp<IBar> bar; | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 330 | sp<IFooCallback> fooCb; | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 331 | sp<IGraph> graphInterface; | 
|  | 332 | sp<IPointer> pointerInterface; | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 333 | sp<IPointer> validationPointerInterface; | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 334 |  | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 335 | template <class T> | 
|  | 336 | void addServer(const std::string &name) { | 
|  | 337 | mPids.push_back({name, forkServer<T>(name)}); | 
|  | 338 | } | 
|  | 339 |  | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 340 | void getServices() { | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 341 |  | 
|  | 342 | manager = IServiceManager::getService("manager"); | 
|  | 343 |  | 
|  | 344 | // alternatively: | 
|  | 345 | // manager = defaultServiceManager() | 
|  | 346 |  | 
|  | 347 | ASSERT_NE(manager, nullptr); | 
|  | 348 | ASSERT_TRUE(manager->isRemote()); // manager is always remote | 
|  | 349 |  | 
| Steven Moreland | aa2b83a | 2016-12-21 15:52:11 -0800 | [diff] [blame] | 350 | tokenManager = ITokenManager::getService("manager"); | 
|  | 351 | ASSERT_NE(tokenManager, nullptr); | 
|  | 352 | ASSERT_TRUE(tokenManager->isRemote()); // tokenManager is always remote | 
|  | 353 |  | 
| Steven Moreland | 2a75353 | 2016-12-15 12:37:49 -0800 | [diff] [blame^] | 354 | ashmemAllocator = IAllocator::getService("ashmem"); | 
|  | 355 | ASSERT_NE(ashmemAllocator, nullptr); | 
|  | 356 | ASSERT_TRUE(ashmemAllocator->isRemote()); // allocator is always remote | 
|  | 357 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 358 | // getStub is true if we are in passthrough mode to skip checking | 
|  | 359 | // binderized server, false for binderized mode. | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 360 |  | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 361 | memoryTest = IMemoryTest::getService("memory", gMode == PASSTHROUGH /* getStub */); | 
|  | 362 | ASSERT_NE(memoryTest, nullptr); | 
|  | 363 | ASSERT_EQ(memoryTest->isRemote(), gMode == BINDERIZED); | 
|  | 364 |  | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 365 | fetcher = IFetcher::getService("fetcher", gMode == PASSTHROUGH /* getStub */); | 
|  | 366 | ASSERT_NE(fetcher, nullptr); | 
|  | 367 | ASSERT_EQ(fetcher->isRemote(), gMode == BINDERIZED); | 
|  | 368 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 369 | foo = IFoo::getService("foo", gMode == PASSTHROUGH /* getStub */); | 
| Yifan Hong | 7a82772 | 2016-10-06 17:20:12 -0700 | [diff] [blame] | 370 | ASSERT_NE(foo, nullptr); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 371 | ASSERT_EQ(foo->isRemote(), gMode == BINDERIZED); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 372 |  | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 373 | dyingFoo = IFoo::getService("dyingFoo", gMode == PASSTHROUGH /* getStub */); | 
|  | 374 | ASSERT_NE(foo, nullptr); | 
|  | 375 | ASSERT_EQ(foo->isRemote(), gMode == BINDERIZED); | 
|  | 376 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 377 | bar = IBar::getService("foo", gMode == PASSTHROUGH /* getStub */); | 
| Yifan Hong | 7a82772 | 2016-10-06 17:20:12 -0700 | [diff] [blame] | 378 | ASSERT_NE(bar, nullptr); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 379 | ASSERT_EQ(bar->isRemote(), gMode == BINDERIZED); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 380 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 381 | fooCb = IFooCallback::getService("foo callback", gMode == PASSTHROUGH /* getStub */); | 
| Yifan Hong | 7a82772 | 2016-10-06 17:20:12 -0700 | [diff] [blame] | 382 | ASSERT_NE(fooCb, nullptr); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 383 | ASSERT_EQ(fooCb->isRemote(), gMode == BINDERIZED); | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 384 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 385 | graphInterface = IGraph::getService("graph", gMode == PASSTHROUGH /* getStub */); | 
| Yifan Hong | 7a82772 | 2016-10-06 17:20:12 -0700 | [diff] [blame] | 386 | ASSERT_NE(graphInterface, nullptr); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 387 | ASSERT_EQ(graphInterface->isRemote(), gMode == BINDERIZED); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 388 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 389 | pointerInterface = IPointer::getService("pointer", gMode == PASSTHROUGH /* getStub */); | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 390 | ASSERT_NE(pointerInterface, nullptr); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 391 | ASSERT_EQ(pointerInterface->isRemote(), gMode == BINDERIZED); | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 392 |  | 
|  | 393 | // use passthrough mode as the validation object. | 
|  | 394 | validationPointerInterface = IPointer::getService("pointer", true /* getStub */); | 
|  | 395 | ASSERT_NE(validationPointerInterface, nullptr); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 396 | } | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 397 |  | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 398 | void killServer(const char *serverName) { | 
|  | 399 | for (const auto &pair : mPids) { | 
|  | 400 | if (pair.first == serverName) { | 
|  | 401 | ::killServer(pair.second, pair.first.c_str()); | 
|  | 402 | } | 
|  | 403 | } | 
|  | 404 | } | 
|  | 405 |  | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 406 | virtual void TearDown() { | 
|  | 407 | // clean up by killing server processes. | 
|  | 408 | ALOGI("Environment tear-down beginning..."); | 
|  | 409 | ALOGI("Killing servers..."); | 
|  | 410 | size_t i = 0; | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 411 | for (const auto &pair : mPids) { | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 412 | ::killServer(pair.second, pair.first.c_str()); | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 413 | } | 
|  | 414 | ALOGI("Servers all killed."); | 
|  | 415 | ALOGI("Environment tear-down complete."); | 
|  | 416 | } | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 417 | }; | 
|  | 418 |  | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 419 | class PassthroughEnvironment : public HidlEnvironmentBase { | 
|  | 420 | private: | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 421 | virtual void SetUp() { | 
|  | 422 | ALOGI("Environment setup beginning..."); | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 423 | // starts this even for passthrough mode. | 
|  | 424 | // this is used in Bar's default implementation | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 425 | addServer<IChild>("child"); | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 426 | sleep(1); | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 427 | getServices(); | 
|  | 428 | ALOGI("Environment setup complete."); | 
|  | 429 | } | 
|  | 430 | }; | 
|  | 431 |  | 
|  | 432 | class BinderizedEnvironment : public HidlEnvironmentBase { | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 433 | public: | 
|  | 434 | virtual void SetUp() { | 
|  | 435 | ALOGI("Environment setup beginning..."); | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 436 |  | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 437 | size_t i = 0; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 438 | addServer<IMemoryTest>("memory"); | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 439 | addServer<IChild>("child"); | 
|  | 440 | addServer<IParent>("parent"); | 
|  | 441 | addServer<IFetcher>("fetcher"); | 
|  | 442 | addServer<IBar>("foo"); | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 443 | addServer<IFoo>("dyingFoo"); | 
| Yifan Hong | ccd782b | 2016-11-28 09:41:46 -0800 | [diff] [blame] | 444 | addServer<IFooCallback>("foo callback"); | 
|  | 445 | addServer<IGraph>("graph"); | 
|  | 446 | addServer<IPointer>("pointer"); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 447 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 448 | sleep(1); | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 449 | getServices(); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 450 | ALOGI("Environment setup complete."); | 
|  | 451 | } | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 452 | }; | 
|  | 453 |  | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 454 | class HidlTest : public ::testing::Test { | 
|  | 455 | public: | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 456 | sp<IServiceManager> manager; | 
| Steven Moreland | aa2b83a | 2016-12-21 15:52:11 -0800 | [diff] [blame] | 457 | sp<ITokenManager> tokenManager; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 458 | sp<IAllocator> ashmemAllocator; | 
|  | 459 | sp<IMemoryTest> memoryTest; | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 460 | sp<IFetcher> fetcher; | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 461 | sp<IFoo> foo; | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 462 | sp<IFoo> dyingFoo; | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 463 | sp<IBar> bar; | 
|  | 464 | sp<IFooCallback> fooCb; | 
|  | 465 | sp<IGraph> graphInterface; | 
|  | 466 | sp<IPointer> pointerInterface; | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 467 | sp<IPointer> validationPointerInterface; | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 468 |  | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 469 | void killServer(const char *serverName) { | 
|  | 470 | HidlEnvironmentBase *env; | 
|  | 471 | if (gMode == BINDERIZED) { | 
|  | 472 | env = gBinderizedEnvironment; | 
|  | 473 | } else { | 
|  | 474 | env = gPassthroughEnvironment; | 
|  | 475 | } | 
|  | 476 | env->killServer(serverName); | 
|  | 477 | } | 
|  | 478 |  | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 479 | virtual void SetUp() override { | 
|  | 480 | ALOGI("Test setup beginning..."); | 
|  | 481 | HidlEnvironmentBase *env; | 
|  | 482 | if (gMode == BINDERIZED) { | 
|  | 483 | env = gBinderizedEnvironment; | 
|  | 484 | } else { | 
|  | 485 | env = gPassthroughEnvironment; | 
|  | 486 | } | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 487 | manager = env->manager; | 
| Steven Moreland | aa2b83a | 2016-12-21 15:52:11 -0800 | [diff] [blame] | 488 | tokenManager = env->tokenManager; | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 489 | ashmemAllocator = env->ashmemAllocator; | 
|  | 490 | memoryTest = env->memoryTest; | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 491 | fetcher = env->fetcher; | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 492 | foo = env->foo; | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 493 | dyingFoo = env->dyingFoo; | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 494 | bar = env->bar; | 
|  | 495 | fooCb = env->fooCb; | 
|  | 496 | graphInterface = env->graphInterface; | 
|  | 497 | pointerInterface = env->pointerInterface; | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 498 | validationPointerInterface = env->validationPointerInterface; | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 499 | ALOGI("Test setup complete"); | 
|  | 500 | } | 
|  | 501 | }; | 
|  | 502 |  | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 503 | TEST_F(HidlTest, ServiceListTest) { | 
|  | 504 | static const std::set<std::string> binderizedSet = { | 
|  | 505 | "android.hardware.tests.pointer@1.0::IPointer/pointer", | 
|  | 506 | "android.hardware.tests.bar@1.0::IBar/foo", | 
|  | 507 | "android.hardware.tests.inheritance@1.0::IFetcher/fetcher", | 
|  | 508 | "android.hardware.tests.foo@1.0::IFooCallback/foo callback", | 
|  | 509 | "android.hardware.tests.inheritance@1.0::IParent/parent", | 
|  | 510 | "android.hardware.tests.inheritance@1.0::IParent/child", | 
|  | 511 | "android.hardware.tests.inheritance@1.0::IChild/child", | 
|  | 512 | "android.hardware.tests.pointer@1.0::IGraph/graph", | 
|  | 513 | "android.hardware.tests.inheritance@1.0::IGrandparent/child", | 
|  | 514 | "android.hardware.tests.foo@1.0::IFoo/foo", | 
|  | 515 | "android.hidl.manager@1.0::IServiceManager/manager", | 
|  | 516 | }; | 
|  | 517 |  | 
|  | 518 | static const std::set<std::string> passthroughSet = { | 
|  | 519 | "android.hidl.manager@1.0::IServiceManager/manager" | 
|  | 520 | }; | 
|  | 521 |  | 
|  | 522 | std::set<std::string> activeSet; | 
|  | 523 |  | 
|  | 524 | switch(gMode) { | 
|  | 525 | case BINDERIZED: { | 
|  | 526 | activeSet = binderizedSet; | 
|  | 527 | } break; | 
|  | 528 |  | 
|  | 529 | case PASSTHROUGH: { | 
|  | 530 | activeSet = passthroughSet; | 
|  | 531 | } break; | 
|  | 532 | default: | 
|  | 533 | EXPECT_TRUE(false) << "unrecognized mode"; | 
|  | 534 | } | 
|  | 535 |  | 
|  | 536 | EXPECT_OK(manager->list([&activeSet](const hidl_vec<hidl_string> ®istered){ | 
|  | 537 | std::set<std::string> registeredSet; | 
|  | 538 |  | 
|  | 539 | for (size_t i = 0; i < registered.size(); i++) { | 
|  | 540 | registeredSet.insert(registered[i]); | 
|  | 541 | } | 
|  | 542 |  | 
|  | 543 | std::set<std::string> difference; | 
|  | 544 | std::set_difference(activeSet.begin(), activeSet.end(), | 
|  | 545 | registeredSet.begin(), registeredSet.end(), | 
|  | 546 | std::inserter(difference, difference.begin())); | 
|  | 547 |  | 
|  | 548 | EXPECT_EQ(difference.size(), 0u) << "service(s) not registered " << to_string(difference); | 
|  | 549 | })); | 
|  | 550 | } | 
|  | 551 |  | 
|  | 552 | // passthrough TODO(b/32747392) | 
|  | 553 | TEST_F(HidlTest, ServiceListByInterfaceTest) { | 
|  | 554 | if (gMode == BINDERIZED) { | 
| Steven Moreland | d39133b | 2016-11-11 12:30:08 -0800 | [diff] [blame] | 555 | EXPECT_OK(manager->listByInterface(IParent::descriptor, | 
| Steven Moreland | 01bcb77 | 2016-11-08 15:57:25 -0800 | [diff] [blame] | 556 | [](const hidl_vec<hidl_string> ®istered) { | 
|  | 557 | std::set<std::string> registeredSet; | 
|  | 558 |  | 
|  | 559 | for (size_t i = 0; i < registered.size(); i++) { | 
|  | 560 | registeredSet.insert(registered[i]); | 
|  | 561 | } | 
|  | 562 |  | 
|  | 563 | std::set<std::string> activeSet = { | 
|  | 564 | "parent", "child" | 
|  | 565 | }; | 
|  | 566 | std::set<std::string> difference; | 
|  | 567 | std::set_difference(activeSet.begin(), activeSet.end(), | 
|  | 568 | registeredSet.begin(), registeredSet.end(), | 
|  | 569 | std::inserter(difference, difference.begin())); | 
|  | 570 |  | 
|  | 571 | EXPECT_EQ(difference.size(), 0u) << "service(s) not registered " << to_string(difference); | 
|  | 572 | })); | 
|  | 573 | } | 
|  | 574 | } | 
|  | 575 |  | 
|  | 576 | // passthrough TODO(b/32747392) | 
|  | 577 | TEST_F(HidlTest, ServiceParentTest) { | 
|  | 578 | if (gMode == BINDERIZED) { | 
|  | 579 | sp<IParent> parent = IParent::getService("child"); | 
|  | 580 |  | 
|  | 581 | EXPECT_NE(parent, nullptr); | 
|  | 582 | } | 
|  | 583 | } | 
|  | 584 |  | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 585 | // passthrough TODO(b/32747392) | 
|  | 586 | TEST_F(HidlTest, ServiceNotificationTest) { | 
|  | 587 | if (gMode == BINDERIZED) { | 
|  | 588 | ServiceNotification *notification = new ServiceNotification(); | 
|  | 589 |  | 
|  | 590 | std::string instanceName = "test-instance"; | 
|  | 591 | EXPECT_TRUE(ISimple::registerForNotifications(instanceName, notification)); | 
|  | 592 |  | 
|  | 593 | ProcessState::self()->setThreadPoolMaxThreadCount(0); | 
|  | 594 | ProcessState::self()->startThreadPool(); | 
|  | 595 |  | 
|  | 596 | Simple* instance = new Simple(1); | 
| Steven Moreland | c7167ca | 2016-11-28 11:29:55 -0800 | [diff] [blame] | 597 | EXPECT_EQ(::android::OK, instance->registerAsService(instanceName)); | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 598 |  | 
|  | 599 | std::unique_lock<std::mutex> lock(notification->mutex); | 
|  | 600 |  | 
|  | 601 | notification->condition.wait_for( | 
|  | 602 | lock, | 
|  | 603 | std::chrono::milliseconds(2), | 
|  | 604 | [¬ification]() { | 
|  | 605 | return notification->getRegistrations().size() >= 1; | 
|  | 606 | }); | 
|  | 607 |  | 
|  | 608 | std::vector<std::string> registrations = notification->getRegistrations(); | 
|  | 609 |  | 
|  | 610 | EXPECT_EQ(registrations.size(), 1u); | 
|  | 611 |  | 
|  | 612 | EXPECT_EQ(to_string(registrations.data(), registrations.size()), | 
| Steven Moreland | d39133b | 2016-11-11 12:30:08 -0800 | [diff] [blame] | 613 | std::string("['") + Simple::descriptor + "/" + instanceName + "']"); | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 614 | } | 
|  | 615 | } | 
|  | 616 |  | 
|  | 617 | // passthrough TODO(b/32747392) | 
|  | 618 | TEST_F(HidlTest, ServiceAllNotificationTest) { | 
|  | 619 | if (gMode == BINDERIZED) { | 
|  | 620 | ServiceNotification *notification = new ServiceNotification(); | 
|  | 621 |  | 
|  | 622 | std::string instanceOne = "test-instance-one"; | 
|  | 623 | std::string instanceTwo = "test-instance-two"; | 
|  | 624 | EXPECT_TRUE(ISimple::registerForNotifications("", notification)); | 
|  | 625 |  | 
|  | 626 | ProcessState::self()->setThreadPoolMaxThreadCount(0); | 
|  | 627 | ProcessState::self()->startThreadPool(); | 
|  | 628 |  | 
|  | 629 | Simple* instanceA = new Simple(1); | 
| Steven Moreland | c7167ca | 2016-11-28 11:29:55 -0800 | [diff] [blame] | 630 | EXPECT_EQ(::android::OK, instanceA->registerAsService(instanceOne)); | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 631 | Simple* instanceB = new Simple(2); | 
| Steven Moreland | c7167ca | 2016-11-28 11:29:55 -0800 | [diff] [blame] | 632 | EXPECT_EQ(::android::OK, instanceB->registerAsService(instanceTwo)); | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 633 |  | 
|  | 634 | std::unique_lock<std::mutex> lock(notification->mutex); | 
|  | 635 |  | 
|  | 636 | notification->condition.wait_for( | 
|  | 637 | lock, | 
|  | 638 | std::chrono::milliseconds(2), | 
|  | 639 | [¬ification]() { | 
|  | 640 | return notification->getRegistrations().size() >= 2; | 
|  | 641 | }); | 
|  | 642 |  | 
|  | 643 | std::vector<std::string> registrations = notification->getRegistrations(); | 
|  | 644 | std::sort(registrations.begin(), registrations.end()); | 
|  | 645 |  | 
|  | 646 | EXPECT_EQ(registrations.size(), 2u); | 
|  | 647 |  | 
| Steven Moreland | d39133b | 2016-11-11 12:30:08 -0800 | [diff] [blame] | 648 | std::string descriptor = ISimple::descriptor; | 
| Steven Moreland | 0693f31 | 2016-11-09 15:06:14 -0800 | [diff] [blame] | 649 |  | 
|  | 650 | EXPECT_EQ(to_string(registrations.data(), registrations.size()), | 
|  | 651 | "['" + descriptor + "/" + instanceOne + "', '" | 
|  | 652 | + descriptor + "/" + instanceTwo + "']"); | 
|  | 653 | } | 
|  | 654 | } | 
|  | 655 |  | 
| Steven Moreland | aa2b83a | 2016-12-21 15:52:11 -0800 | [diff] [blame] | 656 | TEST_F(HidlTest, TestToken) { | 
|  | 657 | Return<uint64_t> ret = tokenManager->createToken(manager); | 
|  | 658 | EXPECT_OK(ret); | 
|  | 659 | uint64_t token = ret; | 
|  | 660 |  | 
|  | 661 | EXPECT_OK(tokenManager->get(token, [&](const auto &store) { | 
|  | 662 | EXPECT_NE(nullptr, store.get()); | 
|  | 663 | sp<IServiceManager> retManager = IServiceManager::castFrom(store); | 
|  | 664 |  | 
|  | 665 | // TODO(b/33818800): should have only one Bp per process | 
|  | 666 | // EXPECT_EQ(manager, retManager); | 
|  | 667 |  | 
|  | 668 | EXPECT_NE(nullptr, retManager.get()); | 
|  | 669 | })); | 
|  | 670 |  | 
|  | 671 | Return<bool> unregisterRet = tokenManager->unregister(token); | 
|  | 672 |  | 
|  | 673 | EXPECT_OK(unregisterRet); | 
|  | 674 | if (unregisterRet.isOk()) { | 
|  | 675 | EXPECT_TRUE(ret); | 
|  | 676 | } | 
|  | 677 | } | 
|  | 678 |  | 
| Martijn Coenen | 99e6beb | 2016-12-01 15:48:42 +0100 | [diff] [blame] | 679 | TEST_F(HidlTest, TestSharedMemory) { | 
|  | 680 | const uint8_t kValue = 0xCA; | 
|  | 681 | hidl_memory mem_copy; | 
|  | 682 | EXPECT_OK(ashmemAllocator->allocate(1024, [&](bool success, const hidl_memory& mem) { | 
|  | 683 | EXPECT_EQ(success, true); | 
|  | 684 |  | 
|  | 685 | sp<IMemory> memory = mapMemory(mem); | 
|  | 686 |  | 
|  | 687 | EXPECT_NE(memory, nullptr); | 
|  | 688 |  | 
|  | 689 | uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())); | 
|  | 690 | EXPECT_NE(data, nullptr); | 
|  | 691 |  | 
|  | 692 | EXPECT_EQ(memory->getSize(), mem.size()); | 
|  | 693 |  | 
|  | 694 | memory->update(); | 
|  | 695 | memset(data, 0, memory->getSize()); | 
|  | 696 | memory->commit(); | 
|  | 697 |  | 
|  | 698 | mem_copy = mem; | 
|  | 699 | memoryTest->fillMemory(mem, kValue); | 
|  | 700 | for (size_t i = 0; i < mem.size(); i++) { | 
|  | 701 | EXPECT_EQ(kValue, data[i]); | 
|  | 702 | } | 
|  | 703 | })); | 
|  | 704 |  | 
|  | 705 | // Test the memory persists after the call | 
|  | 706 | sp<IMemory> memory = mapMemory(mem_copy); | 
|  | 707 |  | 
|  | 708 | EXPECT_NE(memory, nullptr); | 
|  | 709 |  | 
|  | 710 | uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())); | 
|  | 711 | EXPECT_NE(data, nullptr); | 
|  | 712 |  | 
|  | 713 | for (size_t i = 0; i < mem_copy.size(); i++) { | 
|  | 714 | EXPECT_EQ(kValue, data[i]); | 
|  | 715 | } | 
|  | 716 | } | 
|  | 717 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 718 | TEST_F(HidlTest, FooDoThisTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 719 | ALOGI("CLIENT call doThis."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 720 | EXPECT_OK(foo->doThis(1.0f)); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 721 | ALOGI("CLIENT doThis returned."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 722 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 723 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 724 | TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 725 | ALOGI("CLIENT call doThatAndReturnSomething."); | 
| Steven Moreland | 2ae5bca | 2016-12-01 05:56:49 +0000 | [diff] [blame] | 726 | int32_t result = foo->doThatAndReturnSomething(2.0f); | 
|  | 727 | ALOGI("CLIENT doThatAndReturnSomething returned %d.", result); | 
|  | 728 | EXPECT_EQ(result, 666); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 729 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 730 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 731 | TEST_F(HidlTest, FooDoQuiteABitTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 732 | ALOGI("CLIENT call doQuiteABit"); | 
| Steven Moreland | 2ae5bca | 2016-12-01 05:56:49 +0000 | [diff] [blame] | 733 | double something = foo->doQuiteABit(1, 2, 3.0f, 4.0); | 
|  | 734 | ALOGI("CLIENT doQuiteABit returned %f.", something); | 
|  | 735 | EXPECT_DOUBLE_EQ(something, 666.5); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 736 | } | 
|  | 737 |  | 
|  | 738 | TEST_F(HidlTest, FooDoSomethingElseTest) { | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 739 |  | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 740 | ALOGI("CLIENT call doSomethingElse"); | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 741 | hidl_array<int32_t, 15> param; | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 742 | for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) { | 
|  | 743 | param[i] = i; | 
|  | 744 | } | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 745 | EXPECT_OK(foo->doSomethingElse(param, [&](const auto &something) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 746 | ALOGI("CLIENT doSomethingElse returned %s.", | 
| Andreas Huber | 5e44a29 | 2016-09-27 14:52:39 -0700 | [diff] [blame] | 747 | to_string(something).c_str()); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 748 | int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, | 
|  | 749 | 26, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2}; | 
| Steven Moreland | e70455b | 2016-09-14 15:46:36 -0700 | [diff] [blame] | 750 | EXPECT_TRUE(isArrayEqual(something, expect, 32)); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 751 | })); | 
|  | 752 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 753 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 754 | TEST_F(HidlTest, FooDoStuffAndReturnAStringTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 755 | ALOGI("CLIENT call doStuffAndReturnAString"); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 756 | EXPECT_OK(foo->doStuffAndReturnAString([&](const auto &something) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 757 | ALOGI("CLIENT doStuffAndReturnAString returned '%s'.", | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 758 | something.c_str()); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 759 | EXPECT_STREQ(something.c_str(), "Hello, world"); | 
|  | 760 | })); | 
|  | 761 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 762 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 763 | TEST_F(HidlTest, FooMapThisVectorTest) { | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 764 | hidl_vec<int32_t> vecParam; | 
|  | 765 | vecParam.resize(10); | 
|  | 766 | for (size_t i = 0; i < 10; ++i) { | 
|  | 767 | vecParam[i] = i; | 
|  | 768 | } | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 769 | EXPECT_OK(foo->mapThisVector(vecParam, [&](const auto &something) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 770 | ALOGI("CLIENT mapThisVector returned %s.", | 
| Andreas Huber | 5e44a29 | 2016-09-27 14:52:39 -0700 | [diff] [blame] | 771 | to_string(something).c_str()); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 772 | int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}; | 
| Steven Moreland | e70455b | 2016-09-14 15:46:36 -0700 | [diff] [blame] | 773 | EXPECT_TRUE(isArrayEqual(something, expect, something.size())); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 774 | })); | 
|  | 775 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 776 |  | 
| Yifan Hong | def2cfb | 2016-12-14 16:00:24 -0800 | [diff] [blame] | 777 | TEST_F(HidlTest, WrapTest) { | 
|  | 778 | using ::android::hardware::tests::foo::V1_0::BnSimple; | 
|  | 779 | using ::android::hardware::tests::foo::V1_0::BsSimple; | 
|  | 780 | using ::android::hardware::tests::foo::V1_0::BpSimple; | 
|  | 781 | using ::android::hardware::HidlInstrumentor; | 
|  | 782 | nsecs_t now; | 
|  | 783 | int i = 0; | 
|  | 784 |  | 
|  | 785 | now = systemTime(); | 
|  | 786 | new BnSimple(new Simple(1)); | 
|  | 787 | EXPECT_LT(systemTime() - now, 2000000) << "    for BnSimple(nonnull)"; | 
|  | 788 |  | 
|  | 789 | now = systemTime(); | 
|  | 790 | new BnSimple(nullptr); | 
|  | 791 | EXPECT_LT(systemTime() - now, 2000000) << "    for BnSimple(null)"; | 
|  | 792 |  | 
|  | 793 | now = systemTime(); | 
|  | 794 | new BsSimple(new Simple(1)); | 
|  | 795 | EXPECT_LT(systemTime() - now, 2000000) << "    for BsSimple(nonnull)"; | 
|  | 796 |  | 
|  | 797 | now = systemTime(); | 
|  | 798 | new BsSimple(nullptr); | 
|  | 799 | EXPECT_LT(systemTime() - now, 2000000) << "    for BsSimple(null)"; | 
|  | 800 |  | 
|  | 801 | now = systemTime(); | 
|  | 802 | new BpSimple(nullptr); | 
|  | 803 | EXPECT_LT(systemTime() - now, 2000000) << "    for BpSimple(null)"; | 
|  | 804 |  | 
|  | 805 | now = systemTime(); | 
|  | 806 | new ::android::hardware::HidlInstrumentor(""); | 
|  | 807 | EXPECT_LT(systemTime() - now, 2000000) << "    for HidlInstrumentor"; | 
|  | 808 |  | 
|  | 809 | now = systemTime(); | 
|  | 810 | i++; | 
|  | 811 | EXPECT_LT(systemTime() - now,    1000) << "    for nothing"; | 
|  | 812 | } | 
|  | 813 |  | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 814 | // TODO: b/31819198 | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 815 | TEST_F(HidlTest, FooCallMeTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 816 | ALOGI("CLIENT call callMe."); | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 817 | // callMe is oneway, should return instantly. | 
|  | 818 | nsecs_t now; | 
|  | 819 | now = systemTime(); | 
|  | 820 | EXPECT_OK(foo->callMe(fooCb)); | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 821 | EXPECT_LT(systemTime() - now, ONEWAY_TOLERANCE_NS); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 822 | ALOGI("CLIENT callMe returned."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 823 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 824 |  | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 825 | // TODO: b/31819198 | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 826 | TEST_F(HidlTest, ForReportResultsTest) { | 
|  | 827 |  | 
|  | 828 | // Bar::callMe will invoke three methods on FooCallback; one will return | 
|  | 829 | // right away (even though it is a two-way method); the second one will | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 830 | // block Bar for DELAY_S seconds, and the third one will return | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 831 | // to Bar right away (is oneway) but will itself block for DELAY_S seconds. | 
|  | 832 | // We need a way to make sure that these three things have happened within | 
|  | 833 | // 2*DELAY_S seconds plus some small tolerance. | 
|  | 834 | // | 
|  | 835 | // Method FooCallback::reportResults() takes a timeout parameter.  It blocks for | 
|  | 836 | // that length of time, while waiting for the three methods above to | 
|  | 837 | // complete.  It returns the information of whether each method was invoked, | 
|  | 838 | // as well as how long the body of the method took to execute.  We verify | 
|  | 839 | // the information returned by reportResults() against the timeout we pass (which | 
|  | 840 | // is long enough for the method bodies to execute, plus tolerance), and | 
|  | 841 | // verify that eachof them executed, as expected, and took the length of | 
|  | 842 | // time to execute that we also expect. | 
|  | 843 |  | 
|  | 844 | const nsecs_t reportResultsNs = | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 845 | 2 * DELAY_NS + TOLERANCE_NS; | 
| Andreas Huber | 03866f5 | 2016-08-30 14:19:52 -0700 | [diff] [blame] | 846 |  | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 847 | ALOGI("CLIENT: Waiting for up to %" PRId64 " seconds.", | 
|  | 848 | nanoseconds_to_seconds(reportResultsNs)); | 
|  | 849 |  | 
|  | 850 | fooCb->reportResults(reportResultsNs, | 
|  | 851 | [&](int64_t timeLeftNs, | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 852 | const hidl_array<IFooCallback::InvokeInfo, 3> &invokeResults) { | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 853 | ALOGI("CLIENT: FooCallback::reportResults() is returning data."); | 
|  | 854 | ALOGI("CLIENT: Waited for %" PRId64 " milliseconds.", | 
|  | 855 | nanoseconds_to_milliseconds(reportResultsNs - timeLeftNs)); | 
|  | 856 |  | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 857 | EXPECT_LE(0, timeLeftNs); | 
|  | 858 | EXPECT_LE(timeLeftNs, reportResultsNs); | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 859 |  | 
|  | 860 | // two-way method, was supposed to return right away | 
|  | 861 | EXPECT_TRUE(invokeResults[0].invoked); | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 862 | EXPECT_LE(invokeResults[0].timeNs, invokeResults[0].callerBlockedNs); | 
|  | 863 | EXPECT_LE(invokeResults[0].callerBlockedNs, TOLERANCE_NS); | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 864 | // two-way method, was supposed to block caller for DELAY_NS | 
|  | 865 | EXPECT_TRUE(invokeResults[1].invoked); | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 866 | EXPECT_LE(invokeResults[1].timeNs, invokeResults[1].callerBlockedNs); | 
|  | 867 | EXPECT_LE(invokeResults[1].callerBlockedNs, | 
|  | 868 | DELAY_NS + TOLERANCE_NS); | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 869 | // one-way method, do not block caller, but body was supposed to block for DELAY_NS | 
|  | 870 | EXPECT_TRUE(invokeResults[2].invoked); | 
| Yifan Hong | 3eac8a3 | 2016-10-11 10:02:59 -0700 | [diff] [blame] | 871 | EXPECT_LE(invokeResults[2].callerBlockedNs, ONEWAY_TOLERANCE_NS); | 
|  | 872 | EXPECT_LE(invokeResults[2].timeNs, DELAY_NS + TOLERANCE_NS); | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 873 | }); | 
|  | 874 | } | 
|  | 875 |  | 
| Steven Moreland | 2ae5bca | 2016-12-01 05:56:49 +0000 | [diff] [blame] | 876 |  | 
|  | 877 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 878 | TEST_F(HidlTest, FooUseAnEnumTest) { | 
|  | 879 | ALOGI("CLIENT call useAnEnum."); | 
| Steven Moreland | 2ae5bca | 2016-12-01 05:56:49 +0000 | [diff] [blame] | 880 | IFoo::SomeEnum sleepy = foo->useAnEnum(IFoo::SomeEnum::quux); | 
|  | 881 | ALOGI("CLIENT useAnEnum returned %u", (unsigned)sleepy); | 
|  | 882 | EXPECT_EQ(sleepy, IFoo::SomeEnum::goober); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 883 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 884 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 885 | TEST_F(HidlTest, FooHaveAGooberTest) { | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 886 | hidl_vec<IFoo::Goober> gooberVecParam; | 
|  | 887 | gooberVecParam.resize(2); | 
|  | 888 | gooberVecParam[0].name = "Hello"; | 
|  | 889 | gooberVecParam[1].name = "World"; | 
|  | 890 |  | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 891 | ALOGI("CLIENT call haveAGooberVec."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 892 | EXPECT_OK(foo->haveAGooberVec(gooberVecParam)); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 893 | ALOGI("CLIENT haveAGooberVec returned."); | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 894 |  | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 895 | ALOGI("CLIENT call haveaGoober."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 896 | EXPECT_OK(foo->haveAGoober(gooberVecParam[0])); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 897 | ALOGI("CLIENT haveaGoober returned."); | 
|  | 898 |  | 
|  | 899 | ALOGI("CLIENT call haveAGooberArray."); | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 900 | hidl_array<IFoo::Goober, 20> gooberArrayParam; | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 901 | EXPECT_OK(foo->haveAGooberArray(gooberArrayParam)); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 902 | ALOGI("CLIENT haveAGooberArray returned."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 903 | } | 
| Steven Moreland | 88ca451 | 2016-08-11 11:24:10 -0700 | [diff] [blame] | 904 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 905 | TEST_F(HidlTest, FooHaveATypeFromAnotherFileTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 906 | ALOGI("CLIENT call haveATypeFromAnotherFile."); | 
| Steven Moreland | 88ca451 | 2016-08-11 11:24:10 -0700 | [diff] [blame] | 907 | Abc abcParam{}; | 
|  | 908 | abcParam.x = "alphabet"; | 
|  | 909 | abcParam.y = 3.14f; | 
| Yifan Hong | a65bb2c | 2016-10-27 13:17:14 -0700 | [diff] [blame] | 910 | native_handle_t *handle = native_handle_create(0, 0); | 
|  | 911 | abcParam.z = handle; | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 912 | EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam)); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 913 | ALOGI("CLIENT haveATypeFromAnotherFile returned."); | 
| Yifan Hong | a65bb2c | 2016-10-27 13:17:14 -0700 | [diff] [blame] | 914 | native_handle_delete(handle); | 
| Steven Moreland | 88ca451 | 2016-08-11 11:24:10 -0700 | [diff] [blame] | 915 | abcParam.z = NULL; | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 916 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 917 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 918 | TEST_F(HidlTest, FooHaveSomeStringsTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 919 | ALOGI("CLIENT call haveSomeStrings."); | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 920 | hidl_array<hidl_string, 3> stringArrayParam; | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 921 | stringArrayParam[0] = "What"; | 
|  | 922 | stringArrayParam[1] = "a"; | 
|  | 923 | stringArrayParam[2] = "disaster"; | 
| Steven Moreland | 67f67b4 | 2016-09-29 08:59:02 -0700 | [diff] [blame] | 924 | EXPECT_OK(foo->haveSomeStrings( | 
|  | 925 | stringArrayParam, | 
|  | 926 | [&](const auto &out) { | 
|  | 927 | ALOGI("CLIENT haveSomeStrings returned %s.", | 
|  | 928 | to_string(out).c_str()); | 
|  | 929 |  | 
|  | 930 | EXPECT_EQ(to_string(out), "['Hello', 'World']"); | 
|  | 931 | })); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 932 | ALOGI("CLIENT haveSomeStrings returned."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 933 | } | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 934 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 935 | TEST_F(HidlTest, FooHaveAStringVecTest) { | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 936 | ALOGI("CLIENT call haveAStringVec."); | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 937 | hidl_vec<hidl_string> stringVecParam; | 
|  | 938 | stringVecParam.resize(3); | 
|  | 939 | stringVecParam[0] = "What"; | 
|  | 940 | stringVecParam[1] = "a"; | 
|  | 941 | stringVecParam[2] = "disaster"; | 
| Steven Moreland | 67f67b4 | 2016-09-29 08:59:02 -0700 | [diff] [blame] | 942 | EXPECT_OK(foo->haveAStringVec( | 
|  | 943 | stringVecParam, | 
|  | 944 | [&](const auto &out) { | 
|  | 945 | ALOGI("CLIENT haveAStringVec returned %s.", | 
|  | 946 | to_string(out).c_str()); | 
|  | 947 |  | 
|  | 948 | EXPECT_EQ(to_string(out), "['Hello', 'World']"); | 
|  | 949 | })); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 950 | ALOGI("CLIENT haveAStringVec returned."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 951 | } | 
| Andreas Huber | 6cb08cf | 2016-08-03 15:44:51 -0700 | [diff] [blame] | 952 |  | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 953 | TEST_F(HidlTest, FooTransposeMeTest) { | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 954 | hidl_array<float, 3, 5> in; | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 955 | float k = 1.0f; | 
|  | 956 | for (size_t i = 0; i < 3; ++i) { | 
|  | 957 | for (size_t j = 0; j < 5; ++j, ++k) { | 
|  | 958 | in[i][j] = k; | 
|  | 959 | } | 
|  | 960 | } | 
|  | 961 |  | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 962 | ALOGI("CLIENT call transposeMe(%s).", to_string(in).c_str()); | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 963 |  | 
|  | 964 | EXPECT_OK(foo->transposeMe( | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 965 | in, | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 966 | [&](const auto &out) { | 
|  | 967 | ALOGI("CLIENT transposeMe returned %s.", | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 968 | to_string(out).c_str()); | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 969 |  | 
|  | 970 | for (size_t i = 0; i < 3; ++i) { | 
|  | 971 | for (size_t j = 0; j < 5; ++j) { | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 972 | EXPECT_EQ(out[j][i], in[i][j]); | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 973 | } | 
|  | 974 | } | 
|  | 975 | })); | 
|  | 976 | } | 
|  | 977 |  | 
|  | 978 | TEST_F(HidlTest, FooCallingDrWhoTest) { | 
|  | 979 | IFoo::MultiDimensional in; | 
|  | 980 |  | 
|  | 981 | size_t k = 0; | 
|  | 982 | for (size_t i = 0; i < 5; ++i) { | 
|  | 983 | for (size_t j = 0; j < 3; ++j, ++k) { | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 984 | in.quuxMatrix[i][j].first = ("First " + std::to_string(k)).c_str(); | 
|  | 985 | in.quuxMatrix[i][j].last = ("Last " + std::to_string(15-k)).c_str(); | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 986 | } | 
|  | 987 | } | 
|  | 988 |  | 
|  | 989 | ALOGI("CLIENT call callingDrWho(%s).", | 
|  | 990 | MultiDimensionalToString(in).c_str()); | 
|  | 991 |  | 
|  | 992 | EXPECT_OK(foo->callingDrWho( | 
|  | 993 | in, | 
|  | 994 | [&](const auto &out) { | 
|  | 995 | ALOGI("CLIENT callingDrWho returned %s.", | 
|  | 996 | MultiDimensionalToString(out).c_str()); | 
|  | 997 |  | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 998 | size_t k = 0; | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 999 | for (size_t i = 0; i < 5; ++i) { | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1000 | for (size_t j = 0; j < 3; ++j, ++k) { | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 1001 | EXPECT_STREQ( | 
|  | 1002 | out.quuxMatrix[i][j].first.c_str(), | 
|  | 1003 | in.quuxMatrix[4 - i][2 - j].last.c_str()); | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 1004 |  | 
|  | 1005 | EXPECT_STREQ( | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 1006 | out.quuxMatrix[i][j].last.c_str(), | 
|  | 1007 | in.quuxMatrix[4 - i][2 - j].first.c_str()); | 
| Andreas Huber | f9d49f1 | 2016-09-12 14:58:36 -0700 | [diff] [blame] | 1008 | } | 
|  | 1009 | } | 
|  | 1010 | })); | 
|  | 1011 | } | 
|  | 1012 |  | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1013 | static std::string numberToEnglish(int x) { | 
|  | 1014 | static const char *const kDigits[] = { | 
|  | 1015 | "zero", | 
|  | 1016 | "one", | 
|  | 1017 | "two", | 
|  | 1018 | "three", | 
|  | 1019 | "four", | 
|  | 1020 | "five", | 
|  | 1021 | "six", | 
|  | 1022 | "seven", | 
|  | 1023 | "eight", | 
|  | 1024 | "nine", | 
|  | 1025 | }; | 
|  | 1026 |  | 
|  | 1027 | if (x < 0) { | 
|  | 1028 | return "negative " + numberToEnglish(-x); | 
|  | 1029 | } | 
|  | 1030 |  | 
|  | 1031 | if (x < 10) { | 
|  | 1032 | return kDigits[x]; | 
|  | 1033 | } | 
|  | 1034 |  | 
|  | 1035 | if (x <= 15) { | 
|  | 1036 | static const char *const kSpecialTens[] = { | 
|  | 1037 | "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", | 
|  | 1038 | }; | 
|  | 1039 |  | 
|  | 1040 | return kSpecialTens[x - 10]; | 
|  | 1041 | } | 
|  | 1042 |  | 
|  | 1043 | if (x < 20) { | 
|  | 1044 | return std::string(kDigits[x % 10]) + "teen"; | 
|  | 1045 | } | 
|  | 1046 |  | 
|  | 1047 | if (x < 100) { | 
|  | 1048 | static const char *const kDecades[] = { | 
|  | 1049 | "twenty", "thirty", "forty", "fifty", "sixty", "seventy", | 
|  | 1050 | "eighty", "ninety", | 
|  | 1051 | }; | 
|  | 1052 |  | 
|  | 1053 | return std::string(kDecades[x / 10 - 2]) + kDigits[x % 10]; | 
|  | 1054 | } | 
|  | 1055 |  | 
|  | 1056 | return "positively huge!"; | 
|  | 1057 | } | 
|  | 1058 |  | 
|  | 1059 | TEST_F(HidlTest, FooTransposeTest) { | 
|  | 1060 | IFoo::StringMatrix5x3 in; | 
|  | 1061 |  | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1062 | for (int i = 0; i < 5; ++i) { | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 1063 | for (int j = 0; j < 3; ++j) { | 
|  | 1064 | in.s[i][j] = numberToEnglish(3 * i + j + 1).c_str(); | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1065 | } | 
|  | 1066 | } | 
|  | 1067 |  | 
|  | 1068 | EXPECT_OK(foo->transpose( | 
|  | 1069 | in, | 
|  | 1070 | [&](const auto &out) { | 
|  | 1071 | EXPECT_EQ( | 
|  | 1072 | to_string(out), | 
|  | 1073 | "[['one', 'four', 'seven', 'ten', 'thirteen'], " | 
|  | 1074 | "['two', 'five', 'eight', 'eleven', 'fourteen'], " | 
|  | 1075 | "['three', 'six', 'nine', 'twelve', 'fifteen']]"); | 
|  | 1076 | })); | 
|  | 1077 | } | 
|  | 1078 |  | 
|  | 1079 | TEST_F(HidlTest, FooTranspose2Test) { | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 1080 | hidl_array<hidl_string, 5, 3> in; | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1081 |  | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1082 | for (int i = 0; i < 5; ++i) { | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 1083 | for (int j = 0; j < 3; ++j) { | 
|  | 1084 | in[i][j] = numberToEnglish(3 * i + j + 1).c_str(); | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1085 | } | 
|  | 1086 | } | 
|  | 1087 |  | 
|  | 1088 | EXPECT_OK(foo->transpose2( | 
|  | 1089 | in, | 
|  | 1090 | [&](const auto &out) { | 
|  | 1091 | EXPECT_EQ( | 
| Andreas Huber | f03332a | 2016-09-22 15:35:43 -0700 | [diff] [blame] | 1092 | to_string(out), | 
| Andreas Huber | 709b62d | 2016-09-19 11:21:18 -0700 | [diff] [blame] | 1093 | "[['one', 'four', 'seven', 'ten', 'thirteen'], " | 
|  | 1094 | "['two', 'five', 'eight', 'eleven', 'fourteen'], " | 
|  | 1095 | "['three', 'six', 'nine', 'twelve', 'fifteen']]"); | 
|  | 1096 | })); | 
|  | 1097 | } | 
|  | 1098 |  | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1099 | // TODO: enable for passthrough mode after b/30814137 | 
| Yifan Hong | b725d67 | 2016-10-10 10:14:15 -0700 | [diff] [blame] | 1100 | TEST_F(HidlTest, FooNullNativeHandleTest) { | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1101 | if (gMode == BINDERIZED) { | 
|  | 1102 | Abc xyz; | 
|  | 1103 | xyz.z = nullptr; | 
| Yifan Hong | a65bb2c | 2016-10-27 13:17:14 -0700 | [diff] [blame] | 1104 | EXPECT_FAIL(bar->expectNullHandle(nullptr, xyz, [](bool hIsNull, bool xyzHasNull) { | 
|  | 1105 | EXPECT_TRUE(hIsNull); | 
|  | 1106 | EXPECT_TRUE(xyzHasNull); | 
|  | 1107 | })); | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1108 | } | 
| Yifan Hong | b725d67 | 2016-10-10 10:14:15 -0700 | [diff] [blame] | 1109 | } | 
| Steven Moreland | 67f67b4 | 2016-09-29 08:59:02 -0700 | [diff] [blame] | 1110 |  | 
| Martijn Coenen | e163823 | 2016-10-26 12:51:34 +0200 | [diff] [blame] | 1111 | TEST_F(HidlTest, FooNullCallbackTest) { | 
|  | 1112 | EXPECT_OK(foo->echoNullInterface(nullptr, | 
|  | 1113 | [](const auto receivedNull, const auto &intf) { | 
|  | 1114 | EXPECT_TRUE(receivedNull); | 
|  | 1115 | EXPECT_EQ(intf, nullptr); | 
|  | 1116 | })); | 
|  | 1117 | } | 
|  | 1118 |  | 
| Steven Moreland | 67f67b4 | 2016-09-29 08:59:02 -0700 | [diff] [blame] | 1119 | TEST_F(HidlTest, FooNonNullCallbackTest) { | 
|  | 1120 | hidl_array<hidl_string, 5, 3> in; | 
|  | 1121 |  | 
|  | 1122 | EXPECT_FAIL(foo->transpose2(in, nullptr /* _hidl_cb */)); | 
|  | 1123 | } | 
|  | 1124 |  | 
| Andreas Huber | 5e44a29 | 2016-09-27 14:52:39 -0700 | [diff] [blame] | 1125 | TEST_F(HidlTest, FooSendVecTest) { | 
|  | 1126 | hidl_vec<uint8_t> in; | 
|  | 1127 | in.resize(16); | 
|  | 1128 | for (size_t i = 0; i < in.size(); ++i) { | 
|  | 1129 | in[i] = i; | 
|  | 1130 | } | 
|  | 1131 |  | 
|  | 1132 | EXPECT_OK(foo->sendVec( | 
|  | 1133 | in, | 
|  | 1134 | [&](const auto &out) { | 
|  | 1135 | EXPECT_EQ(to_string(in), to_string(out)); | 
|  | 1136 | })); | 
|  | 1137 | } | 
|  | 1138 |  | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 1139 | TEST_F(HidlTest, FooHaveAVectorOfInterfacesTest) { | 
|  | 1140 | hidl_vec<sp<ISimple> > in; | 
|  | 1141 | in.resize(16); | 
|  | 1142 | for (size_t i = 0; i < in.size(); ++i) { | 
|  | 1143 | in[i] = new Simple(i); | 
|  | 1144 | } | 
|  | 1145 |  | 
|  | 1146 | EXPECT_OK(foo->haveAVectorOfInterfaces( | 
|  | 1147 | in, | 
|  | 1148 | [&](const auto &out) { | 
|  | 1149 | EXPECT_EQ(in.size(), out.size()); | 
|  | 1150 | for (size_t i = 0; i < in.size(); ++i) { | 
| Steven Moreland | 2ae5bca | 2016-12-01 05:56:49 +0000 | [diff] [blame] | 1151 | int32_t inCookie = in[i]->getCookie(); | 
|  | 1152 | int32_t outCookie = out[i]->getCookie(); | 
|  | 1153 | EXPECT_EQ(inCookie, outCookie); | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 1154 | } | 
|  | 1155 | })); | 
|  | 1156 | } | 
|  | 1157 |  | 
|  | 1158 | TEST_F(HidlTest, FooHaveAVectorOfGenericInterfacesTest) { | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 1159 |  | 
| Yifan Hong | c893404 | 2016-11-17 17:10:52 -0800 | [diff] [blame] | 1160 | hidl_vec<sp<::android::hidl::base::V1_0::IBase> > in; | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 1161 | in.resize(16); | 
|  | 1162 | for (size_t i = 0; i < in.size(); ++i) { | 
| Yifan Hong | c893404 | 2016-11-17 17:10:52 -0800 | [diff] [blame] | 1163 | sp<ISimple> s = new Simple(i); | 
|  | 1164 | in[i] = s; | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 1165 | } | 
|  | 1166 |  | 
|  | 1167 | EXPECT_OK(foo->haveAVectorOfGenericInterfaces( | 
|  | 1168 | in, | 
|  | 1169 | [&](const auto &out) { | 
|  | 1170 | EXPECT_EQ(in.size(), out.size()); | 
| Yifan Hong | c893404 | 2016-11-17 17:10:52 -0800 | [diff] [blame] | 1171 |  | 
|  | 1172 | EXPECT_OK(out[0]->interfaceChain([](const auto &names) { | 
|  | 1173 | ASSERT_GT(names.size(), 0u); | 
|  | 1174 | ASSERT_STREQ(names[0].c_str(), ISimple::descriptor); | 
|  | 1175 | })); | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 1176 | for (size_t i = 0; i < in.size(); ++i) { | 
| Yifan Hong | c893404 | 2016-11-17 17:10:52 -0800 | [diff] [blame] | 1177 | sp<ISimple> inSimple = ISimple::castFrom(in[i]); | 
|  | 1178 | sp<ISimple> outSimple = ISimple::castFrom(out[i]); | 
|  | 1179 |  | 
|  | 1180 | ASSERT_NE(inSimple.get(), nullptr); | 
|  | 1181 | ASSERT_NE(outSimple.get(), nullptr); | 
| Martijn Coenen | 6ec2f0b | 2016-12-11 01:04:55 +0100 | [diff] [blame] | 1182 | EXPECT_EQ(in[i], inSimple.get()); // pointers must be equal! | 
| Steven Moreland | 2ae5bca | 2016-12-01 05:56:49 +0000 | [diff] [blame] | 1183 | int32_t inCookie = inSimple->getCookie(); | 
|  | 1184 | int32_t outCookie = outSimple->getCookie(); | 
|  | 1185 | EXPECT_EQ(inCookie, outCookie); | 
| Andreas Huber | 86a112b | 2016-10-19 14:25:16 -0700 | [diff] [blame] | 1186 | } | 
|  | 1187 | })); | 
|  | 1188 | } | 
|  | 1189 |  | 
| Yifan Hong | 8c48ad7 | 2016-10-14 11:34:59 -0700 | [diff] [blame] | 1190 | TEST_F(HidlTest, FooStructEmbeddedHandleTest) { | 
|  | 1191 | EXPECT_OK(foo->createMyHandle([&](const auto &myHandle) { | 
|  | 1192 | EXPECT_EQ(myHandle.guard, 666); | 
| Martijn Coenen | 2f69a5b | 2016-11-18 15:26:38 +0100 | [diff] [blame] | 1193 | const native_handle_t* handle = myHandle.h.getNativeHandle(); | 
|  | 1194 | EXPECT_EQ(handle->numInts, 10); | 
|  | 1195 | EXPECT_EQ(handle->numFds, 0); | 
| Yifan Hong | 8c48ad7 | 2016-10-14 11:34:59 -0700 | [diff] [blame] | 1196 | int data[] = {2,3,5,7,11,13,17,19,21,23}; | 
| Martijn Coenen | 2f69a5b | 2016-11-18 15:26:38 +0100 | [diff] [blame] | 1197 | EXPECT_ARRAYEQ(handle->data, data, 10); | 
| Yifan Hong | 8c48ad7 | 2016-10-14 11:34:59 -0700 | [diff] [blame] | 1198 | })); | 
|  | 1199 |  | 
|  | 1200 | EXPECT_OK(foo->closeHandles()); | 
|  | 1201 | } | 
|  | 1202 |  | 
|  | 1203 | TEST_F(HidlTest, FooHandleVecTest) { | 
|  | 1204 | EXPECT_OK(foo->createHandles(3, [&](const auto &handles) { | 
|  | 1205 | EXPECT_EQ(handles.size(), 3ull); | 
|  | 1206 | int data[] = {2,3,5,7,11,13,17,19,21,23}; | 
|  | 1207 | for (size_t i = 0; i < 3; i++) { | 
|  | 1208 | const native_handle_t *h = handles[i]; | 
|  | 1209 | EXPECT_EQ(h->numInts, 10) << " for element " << i; | 
|  | 1210 | EXPECT_EQ(h->numFds, 0) << " for element " << i; | 
|  | 1211 | EXPECT_ARRAYEQ(h->data, data, 10); | 
|  | 1212 | } | 
|  | 1213 | })); | 
|  | 1214 |  | 
|  | 1215 | EXPECT_OK(foo->closeHandles()); | 
|  | 1216 | } | 
|  | 1217 |  | 
| Martijn Coenen | 115d428 | 2016-12-19 05:14:04 +0100 | [diff] [blame] | 1218 | struct HidlDeathRecipient : hidl_death_recipient { | 
|  | 1219 | std::mutex mutex; | 
|  | 1220 | std::condition_variable condition; | 
|  | 1221 | wp<IBase> who; | 
|  | 1222 | bool fired = false; | 
|  | 1223 | uint64_t cookie = 0; | 
|  | 1224 |  | 
|  | 1225 | virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) { | 
|  | 1226 | std::unique_lock<std::mutex> lock(mutex); | 
|  | 1227 | fired = true; | 
|  | 1228 | this->cookie = cookie; | 
|  | 1229 | this->who = who; | 
|  | 1230 | condition.notify_one(); | 
|  | 1231 | }; | 
|  | 1232 | }; | 
|  | 1233 |  | 
|  | 1234 | TEST_F(HidlTest, DeathRecipientTest) { | 
|  | 1235 | // Need a threadpool to receive death calls from the kernel | 
|  | 1236 | ProcessState::self()->setThreadPoolMaxThreadCount(0); | 
|  | 1237 | ProcessState::self()->startThreadPool(); | 
|  | 1238 |  | 
|  | 1239 | sp<HidlDeathRecipient> recipient = new HidlDeathRecipient(); | 
|  | 1240 | sp<HidlDeathRecipient> recipient2 = new HidlDeathRecipient(); | 
|  | 1241 |  | 
|  | 1242 | EXPECT_TRUE(dyingFoo->linkToDeath(recipient, 0x1481)); | 
|  | 1243 | EXPECT_TRUE(dyingFoo->linkToDeath(recipient2, 0x2592)); | 
|  | 1244 | EXPECT_TRUE(dyingFoo->unlinkToDeath(recipient2)); | 
|  | 1245 |  | 
|  | 1246 | if (gMode != BINDERIZED) { | 
|  | 1247 | // Passthrough doesn't fire, nor does it keep state of | 
|  | 1248 | // registered death recipients (so it won't fail unlinking | 
|  | 1249 | // the same recipient twice). | 
|  | 1250 | return; | 
|  | 1251 | } | 
|  | 1252 |  | 
|  | 1253 | EXPECT_FALSE(dyingFoo->unlinkToDeath(recipient2)); | 
|  | 1254 | killServer("dyingFoo"); | 
|  | 1255 |  | 
|  | 1256 | std::unique_lock<std::mutex> lock(recipient->mutex); | 
|  | 1257 | recipient->condition.wait_for(lock, std::chrono::milliseconds(1000), [&recipient]() { | 
|  | 1258 | return recipient->fired; | 
|  | 1259 | }); | 
|  | 1260 | EXPECT_TRUE(recipient->fired); | 
|  | 1261 | EXPECT_EQ(recipient->cookie, 0x1481u); | 
|  | 1262 | EXPECT_EQ(recipient->who, dyingFoo); | 
|  | 1263 | std::unique_lock<std::mutex> lock2(recipient2->mutex); | 
|  | 1264 | recipient2->condition.wait_for(lock2, std::chrono::milliseconds(1000), [&recipient2]() { | 
|  | 1265 | return recipient2->fired; | 
|  | 1266 | }); | 
|  | 1267 | EXPECT_FALSE(recipient2->fired); | 
|  | 1268 |  | 
|  | 1269 | // Verify servicemanager dropped its reference too | 
|  | 1270 | sp<IFoo> deadFoo = IFoo::getService("dyingFoo", false); | 
|  | 1271 | if (deadFoo != nullptr) { | 
|  | 1272 | // Got a passthrough | 
|  | 1273 | EXPECT_FALSE(deadFoo->isRemote()); | 
|  | 1274 | } | 
|  | 1275 | } | 
|  | 1276 |  | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 1277 | TEST_F(HidlTest, BarThisIsNewTest) { | 
| Iliyan Malchev | 0acf419 | 2016-08-22 19:33:20 -0700 | [diff] [blame] | 1278 | // Now the tricky part, get access to the derived interface. | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 1279 | ALOGI("CLIENT call thisIsNew."); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 1280 | EXPECT_OK(bar->thisIsNew()); | 
| Iliyan Malchev | b31e10c | 2016-08-13 23:03:25 -0700 | [diff] [blame] | 1281 | ALOGI("CLIENT thisIsNew returned."); | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 1282 | } | 
|  | 1283 |  | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 1284 | static void expectGoodChild(const sp<IChild> &child) { | 
|  | 1285 | ASSERT_NE(child.get(), nullptr); | 
|  | 1286 | EXPECT_OK(child->doGrandparent()); | 
|  | 1287 | EXPECT_OK(child->doParent()); | 
|  | 1288 | EXPECT_OK(child->doChild()); | 
|  | 1289 | } | 
|  | 1290 |  | 
|  | 1291 | static void expectGoodParent(const sp<IParent> &parent) { | 
|  | 1292 | ASSERT_NE(parent.get(), nullptr); | 
|  | 1293 | EXPECT_OK(parent->doGrandparent()); | 
|  | 1294 | EXPECT_OK(parent->doParent()); | 
|  | 1295 | sp<IChild> child = IChild::castFrom(parent); | 
|  | 1296 | expectGoodChild(child); | 
|  | 1297 | } | 
|  | 1298 |  | 
|  | 1299 | static void expectGoodGrandparent(const sp<IGrandparent> &grandparent) { | 
|  | 1300 | ASSERT_NE(grandparent.get(), nullptr); | 
|  | 1301 | EXPECT_OK(grandparent->doGrandparent()); | 
|  | 1302 | sp<IParent> parent = IParent::castFrom(grandparent); | 
|  | 1303 | expectGoodParent(parent); | 
|  | 1304 | } | 
|  | 1305 |  | 
| Yifan Hong | 5749b2c | 2016-11-28 12:52:36 -0800 | [diff] [blame] | 1306 | TEST_F(HidlTest, FooHaveAnInterfaceTest) { | 
|  | 1307 |  | 
|  | 1308 | sp<ISimple> in = new Complicated(42); | 
|  | 1309 |  | 
|  | 1310 | EXPECT_OK(bar->haveAInterface( | 
|  | 1311 | in, | 
|  | 1312 | [&](const auto &out) { | 
|  | 1313 | ASSERT_NE(out.get(), nullptr); | 
|  | 1314 | EXPECT_EQ(out->getCookie(), 42); | 
|  | 1315 | EXPECT_OK(out->customVecInt([&](const auto &) { })); | 
|  | 1316 | EXPECT_OK(out->customVecStr([&](const auto &) { })); | 
|  | 1317 | EXPECT_OK(out->interfaceChain([&](const auto &) { })); | 
|  | 1318 | EXPECT_OK(out->mystr([&](const auto &) { })); | 
|  | 1319 | EXPECT_OK(out->myhandle([&](const auto &) { })); | 
|  | 1320 | })); | 
|  | 1321 | } | 
|  | 1322 |  | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 1323 | TEST_F(HidlTest, InheritRemoteGrandparentTest) { | 
|  | 1324 | EXPECT_OK(fetcher->getGrandparent(true, [&](const sp<IGrandparent>& grandparent) { | 
|  | 1325 | expectGoodGrandparent(grandparent); | 
|  | 1326 | })); | 
|  | 1327 | } | 
|  | 1328 |  | 
|  | 1329 | TEST_F(HidlTest, InheritLocalGrandparentTest) { | 
|  | 1330 | EXPECT_OK(fetcher->getGrandparent(false, [&](const sp<IGrandparent>& grandparent) { | 
|  | 1331 | expectGoodGrandparent(grandparent); | 
|  | 1332 | })); | 
|  | 1333 | } | 
|  | 1334 |  | 
| Yifan Hong | 4b0214d | 2016-12-07 14:57:57 -0800 | [diff] [blame] | 1335 | TEST_F(HidlTest, InheritRemoteParentTest) { | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 1336 | EXPECT_OK(fetcher->getParent(true, [&](const sp<IParent>& parent) { | 
|  | 1337 | expectGoodParent(parent); | 
|  | 1338 | })); | 
|  | 1339 | } | 
|  | 1340 |  | 
| Yifan Hong | 4b0214d | 2016-12-07 14:57:57 -0800 | [diff] [blame] | 1341 | TEST_F(HidlTest, InheritLocalParentTest) { | 
| Yifan Hong | 1e81c53 | 2016-10-18 18:43:46 -0700 | [diff] [blame] | 1342 | EXPECT_OK(fetcher->getParent(false, [&](const sp<IParent>& parent) { | 
|  | 1343 | expectGoodParent(parent); | 
|  | 1344 | })); | 
|  | 1345 | } | 
|  | 1346 |  | 
|  | 1347 | TEST_F(HidlTest, InheritRemoteChildTest) { | 
|  | 1348 | EXPECT_OK(fetcher->getChild(true, [&](const sp<IChild>& child) { | 
|  | 1349 | expectGoodChild(child); | 
|  | 1350 | })); | 
|  | 1351 | } | 
|  | 1352 |  | 
|  | 1353 | TEST_F(HidlTest, InheritLocalChildTest) { | 
|  | 1354 | EXPECT_OK(fetcher->getChild(false, [&](const sp<IChild>& child) { | 
|  | 1355 | expectGoodChild(child); | 
|  | 1356 | })); | 
|  | 1357 | } | 
|  | 1358 |  | 
| Andreas Huber | 5d03477 | 2016-09-28 14:23:51 -0700 | [diff] [blame] | 1359 | TEST_F(HidlTest, TestArrayDimensionality) { | 
|  | 1360 | hidl_array<int, 2> oneDim; | 
|  | 1361 | hidl_array<int, 2, 3> twoDim; | 
|  | 1362 | hidl_array<int, 2, 3, 4> threeDim; | 
|  | 1363 |  | 
|  | 1364 | EXPECT_EQ(oneDim.size(), 2u); | 
|  | 1365 | EXPECT_EQ(twoDim.size(), std::make_tuple(2u, 3u)); | 
|  | 1366 | EXPECT_EQ(threeDim.size(), std::make_tuple(2u, 3u, 4u)); | 
|  | 1367 | } | 
|  | 1368 |  | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1369 | #if HIDL_RUN_POINTER_TESTS | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 1370 |  | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1371 | TEST_F(HidlTest, PassAGraphTest) { | 
|  | 1372 | IGraph::Graph g; | 
| Yifan Hong | 398e6fb | 2016-10-17 11:38:09 -0700 | [diff] [blame] | 1373 | ::android::simpleGraph(g); | 
|  | 1374 | ::android::logSimpleGraph("CLIENT", g); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1375 | ALOGI("CLIENT call passAGraph"); | 
|  | 1376 | EXPECT_OK(graphInterface->passAGraph(g)); | 
|  | 1377 | } | 
|  | 1378 |  | 
|  | 1379 | TEST_F(HidlTest, GiveAGraphTest) { | 
|  | 1380 | EXPECT_OK(graphInterface->giveAGraph([&](const auto &newGraph) { | 
| Yifan Hong | 398e6fb | 2016-10-17 11:38:09 -0700 | [diff] [blame] | 1381 | ::android::logSimpleGraph("CLIENT", newGraph); | 
|  | 1382 | EXPECT_TRUE(::android::isSimpleGraph(newGraph)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1383 | })); | 
|  | 1384 | } | 
|  | 1385 | TEST_F(HidlTest, PassANodeTest) { | 
|  | 1386 | IGraph::Node node; node.data = 10; | 
|  | 1387 | EXPECT_OK(graphInterface->passANode(node)); | 
|  | 1388 | } | 
|  | 1389 | TEST_F(HidlTest, PassTwoGraphsTest) { | 
|  | 1390 | IGraph::Graph g; | 
| Yifan Hong | 398e6fb | 2016-10-17 11:38:09 -0700 | [diff] [blame] | 1391 | ::android::simpleGraph(g); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1392 | EXPECT_OK(graphInterface->passTwoGraphs(&g, &g)); | 
|  | 1393 | } | 
|  | 1394 | TEST_F(HidlTest, PassAGammaTest) { | 
|  | 1395 | IGraph::Theta s; s.data = 500; | 
|  | 1396 | IGraph::Alpha a; a.s_ptr = &s; | 
|  | 1397 | IGraph::Beta  b; b.s_ptr = &s; | 
|  | 1398 | IGraph::Gamma c; c.a_ptr = &a; c.b_ptr = &b; | 
|  | 1399 | ALOGI("CLIENT calling passAGamma: c.a = %p, c.b = %p, c.a->s = %p, c.b->s = %p", | 
|  | 1400 | c.a_ptr, c.b_ptr, c.a_ptr->s_ptr, c.b_ptr->s_ptr); | 
|  | 1401 | EXPECT_OK(graphInterface->passAGamma(c)); | 
|  | 1402 | } | 
|  | 1403 | TEST_F(HidlTest, PassNullTest) { | 
|  | 1404 | IGraph::Gamma c; | 
|  | 1405 | c.a_ptr = nullptr; | 
|  | 1406 | c.b_ptr = nullptr; | 
|  | 1407 | EXPECT_OK(graphInterface->passAGamma(c)); | 
|  | 1408 | } | 
|  | 1409 | TEST_F(HidlTest, PassASimpleRefTest) { | 
|  | 1410 | IGraph::Theta s; | 
|  | 1411 | s.data = 500; | 
|  | 1412 | IGraph::Alpha a; | 
|  | 1413 | a.s_ptr = &s; | 
|  | 1414 | EXPECT_OK(graphInterface->passASimpleRef(&a)); | 
|  | 1415 | } | 
|  | 1416 | TEST_F(HidlTest, PassASimpleRefSTest) { | 
|  | 1417 | IGraph::Theta s; | 
|  | 1418 | s.data = 500; | 
|  | 1419 | ALOGI("CLIENT call passASimpleRefS with %p", &s); | 
|  | 1420 | EXPECT_OK(graphInterface->passASimpleRefS(&s)); | 
|  | 1421 | } | 
|  | 1422 | TEST_F(HidlTest, GiveASimpleRefTest) { | 
|  | 1423 | EXPECT_OK(graphInterface->giveASimpleRef([&](const auto & a_ptr) { | 
|  | 1424 | EXPECT_EQ(a_ptr->s_ptr->data, 500); | 
|  | 1425 | })); | 
|  | 1426 | } | 
|  | 1427 | TEST_F(HidlTest, GraphReportErrorsTest) { | 
|  | 1428 | Return<int32_t> ret = graphInterface->getErrors(); | 
|  | 1429 | EXPECT_OK(ret); | 
|  | 1430 | EXPECT_EQ(int32_t(ret), 0); | 
|  | 1431 | } | 
|  | 1432 |  | 
|  | 1433 | TEST_F(HidlTest, PointerPassOldBufferTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1434 | EXPECT_OK(validationPointerInterface->bar1([&](const auto& sptr, const auto& s) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1435 | EXPECT_OK(pointerInterface->foo1(sptr, s)); | 
|  | 1436 | })); | 
|  | 1437 | } | 
|  | 1438 | TEST_F(HidlTest, PointerPassOldBufferTest2) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1439 | EXPECT_OK(validationPointerInterface->bar2([&](const auto& s, const auto& a) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1440 | EXPECT_OK(pointerInterface->foo2(s, a)); | 
|  | 1441 | })); | 
|  | 1442 | } | 
|  | 1443 | TEST_F(HidlTest, PointerPassSameOldBufferPointerTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1444 | EXPECT_OK(validationPointerInterface->bar3([&](const auto& s, const auto& a, const auto& b) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1445 | EXPECT_OK(pointerInterface->foo3(s, a, b)); | 
|  | 1446 | })); | 
|  | 1447 | } | 
|  | 1448 | TEST_F(HidlTest, PointerPassOnlyTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1449 | EXPECT_OK(validationPointerInterface->bar4([&](const auto& s) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1450 | EXPECT_OK(pointerInterface->foo4(s)); | 
|  | 1451 | })); | 
|  | 1452 | } | 
|  | 1453 | TEST_F(HidlTest, PointerPassTwoEmbeddedTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1454 | EXPECT_OK(validationPointerInterface->bar5([&](const auto& a, const auto& b) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1455 | EXPECT_OK(pointerInterface->foo5(a, b)); | 
|  | 1456 | })); | 
|  | 1457 | } | 
|  | 1458 | TEST_F(HidlTest, PointerPassIndirectBufferHasDataTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1459 | EXPECT_OK(validationPointerInterface->bar6([&](const auto& a) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1460 | EXPECT_OK(pointerInterface->foo6(a)); | 
|  | 1461 | })); | 
|  | 1462 | } | 
|  | 1463 | TEST_F(HidlTest, PointerPassTwoIndirectBufferTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1464 | EXPECT_OK(validationPointerInterface->bar7([&](const auto& a, const auto& b) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1465 | EXPECT_OK(pointerInterface->foo7(a, b)); | 
|  | 1466 | })); | 
|  | 1467 | } | 
|  | 1468 | TEST_F(HidlTest, PointerPassDeeplyIndirectTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1469 | EXPECT_OK(validationPointerInterface->bar8([&](const auto& d) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1470 | EXPECT_OK(pointerInterface->foo8(d)); | 
|  | 1471 | })); | 
|  | 1472 | } | 
|  | 1473 | TEST_F(HidlTest, PointerPassStringRefTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1474 | EXPECT_OK(validationPointerInterface->bar9([&](const auto& str) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1475 | EXPECT_OK(pointerInterface->foo9(str)); | 
|  | 1476 | })); | 
|  | 1477 | } | 
|  | 1478 | TEST_F(HidlTest, PointerPassRefVecTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1479 | EXPECT_OK(validationPointerInterface->bar10([&](const auto& v) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1480 | EXPECT_OK(pointerInterface->foo10(v)); | 
|  | 1481 | })); | 
|  | 1482 | } | 
|  | 1483 | TEST_F(HidlTest, PointerPassVecRefTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1484 | EXPECT_OK(validationPointerInterface->bar11([&](const auto& v) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1485 | EXPECT_OK(pointerInterface->foo11(v)); | 
|  | 1486 | })); | 
|  | 1487 | } | 
|  | 1488 | TEST_F(HidlTest, PointerPassArrayRefTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1489 | EXPECT_OK(validationPointerInterface->bar12([&](const auto& array) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1490 | EXPECT_OK(pointerInterface->foo12(array)); | 
|  | 1491 | })); | 
|  | 1492 | } | 
|  | 1493 | TEST_F(HidlTest, PointerPassRefArrayTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1494 | EXPECT_OK(validationPointerInterface->bar13([&](const auto& array) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1495 | EXPECT_OK(pointerInterface->foo13(array)); | 
|  | 1496 | })); | 
|  | 1497 | } | 
|  | 1498 | TEST_F(HidlTest, PointerPass3RefTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1499 | EXPECT_OK(validationPointerInterface->bar14([&](const auto& p3) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1500 | EXPECT_OK(pointerInterface->foo14(p3)); | 
|  | 1501 | })); | 
|  | 1502 | } | 
|  | 1503 | TEST_F(HidlTest, PointerPassInt3RefTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1504 | EXPECT_OK(validationPointerInterface->bar15([&](const auto& p3) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1505 | EXPECT_OK(pointerInterface->foo15(p3)); | 
|  | 1506 | })); | 
|  | 1507 | } | 
|  | 1508 | TEST_F(HidlTest, PointerPassEmbeddedPointersTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1509 | EXPECT_OK(validationPointerInterface->bar16([&](const auto& p) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1510 | EXPECT_OK(pointerInterface->foo16(p)); | 
|  | 1511 | })); | 
|  | 1512 | } | 
|  | 1513 | TEST_F(HidlTest, PointerPassEmbeddedPointers2Test) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1514 | EXPECT_OK(validationPointerInterface->bar17([&](const auto& p) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1515 | EXPECT_OK(pointerInterface->foo17(p)); | 
|  | 1516 | })); | 
|  | 1517 | } | 
|  | 1518 | TEST_F(HidlTest, PointerPassCopiedStringTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1519 | EXPECT_OK(validationPointerInterface->bar18([&](const auto& str_ref, const auto& str_ref2, const auto& str) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1520 | EXPECT_OK(pointerInterface->foo18(str_ref, str_ref2, str)); | 
|  | 1521 | })); | 
|  | 1522 | } | 
|  | 1523 | TEST_F(HidlTest, PointerPassCopiedVecTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1524 | EXPECT_OK(validationPointerInterface->bar19([&](const auto& a_vec_ref, const auto& a_vec, const auto& a_vec_ref2) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1525 | EXPECT_OK(pointerInterface->foo19(a_vec_ref, a_vec, a_vec_ref2)); | 
|  | 1526 | })); | 
|  | 1527 | } | 
| Yifan Hong | 8446590 | 2016-09-27 15:52:17 -0700 | [diff] [blame] | 1528 | TEST_F(HidlTest, PointerPassBigRefVecTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1529 | EXPECT_OK(validationPointerInterface->bar20([&](const auto& v) { | 
| Yifan Hong | 8446590 | 2016-09-27 15:52:17 -0700 | [diff] [blame] | 1530 | EXPECT_FAIL(pointerInterface->foo20(v)); | 
|  | 1531 | })); | 
|  | 1532 | } | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1533 | TEST_F(HidlTest, PointerPassMultidimArrayRefTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1534 | EXPECT_OK(validationPointerInterface->bar21([&](const auto& v) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1535 | EXPECT_OK(pointerInterface->foo21(v)); | 
|  | 1536 | })); | 
|  | 1537 | } | 
|  | 1538 | TEST_F(HidlTest, PointerPassRefMultidimArrayTest) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1539 | EXPECT_OK(validationPointerInterface->bar22([&](const auto& v) { | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1540 | EXPECT_OK(pointerInterface->foo22(v)); | 
|  | 1541 | })); | 
|  | 1542 | } | 
|  | 1543 | TEST_F(HidlTest, PointerGiveOldBufferTest) { | 
|  | 1544 | EXPECT_OK(pointerInterface->bar1([&](const auto& sptr, const auto& s) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1545 | EXPECT_OK(validationPointerInterface->foo1(sptr, s)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1546 | })); | 
|  | 1547 | } | 
|  | 1548 | TEST_F(HidlTest, PointerGiveOldBufferTest2) { | 
|  | 1549 | EXPECT_OK(pointerInterface->bar2([&](const auto& s, const auto& a) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1550 | EXPECT_OK(validationPointerInterface->foo2(s, a)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1551 | })); | 
|  | 1552 | } | 
|  | 1553 | TEST_F(HidlTest, PointerGiveSameOldBufferPointerTest) { | 
|  | 1554 | EXPECT_OK(pointerInterface->bar3([&](const auto& s, const auto& a, const auto& b) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1555 | EXPECT_OK(validationPointerInterface->foo3(s, a, b)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1556 | })); | 
|  | 1557 | } | 
|  | 1558 | TEST_F(HidlTest, PointerGiveOnlyTest) { | 
|  | 1559 | EXPECT_OK(pointerInterface->bar4([&](const auto& s) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1560 | EXPECT_OK(validationPointerInterface->foo4(s)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1561 | })); | 
|  | 1562 | } | 
|  | 1563 | TEST_F(HidlTest, PointerGiveTwoEmbeddedTest) { | 
|  | 1564 | EXPECT_OK(pointerInterface->bar5([&](const auto& a, const auto& b) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1565 | EXPECT_OK(validationPointerInterface->foo5(a, b)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1566 | })); | 
|  | 1567 | } | 
|  | 1568 | TEST_F(HidlTest, PointerGiveIndirectBufferHasDataTest) { | 
|  | 1569 | EXPECT_OK(pointerInterface->bar6([&](const auto& a) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1570 | EXPECT_OK(validationPointerInterface->foo6(a)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1571 | })); | 
|  | 1572 | } | 
|  | 1573 | TEST_F(HidlTest, PointerGiveTwoIndirectBufferTest) { | 
|  | 1574 | EXPECT_OK(pointerInterface->bar7([&](const auto& a, const auto& b) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1575 | EXPECT_OK(validationPointerInterface->foo7(a, b)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1576 | })); | 
|  | 1577 | } | 
|  | 1578 | TEST_F(HidlTest, PointerGiveDeeplyIndirectTest) { | 
|  | 1579 | EXPECT_OK(pointerInterface->bar8([&](const auto& d) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1580 | EXPECT_OK(validationPointerInterface->foo8(d)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1581 | })); | 
|  | 1582 | } | 
|  | 1583 | TEST_F(HidlTest, PointerGiveStringRefTest) { | 
|  | 1584 | EXPECT_OK(pointerInterface->bar9([&](const auto& str) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1585 | EXPECT_OK(validationPointerInterface->foo9(str)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1586 | })); | 
|  | 1587 | } | 
|  | 1588 | TEST_F(HidlTest, PointerGiveRefVecTest) { | 
|  | 1589 | EXPECT_OK(pointerInterface->bar10([&](const auto& v) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1590 | EXPECT_OK(validationPointerInterface->foo10(v)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1591 | })); | 
|  | 1592 | } | 
|  | 1593 | TEST_F(HidlTest, PointerGiveVecRefTest) { | 
|  | 1594 | EXPECT_OK(pointerInterface->bar11([&](const auto& v) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1595 | EXPECT_OK(validationPointerInterface->foo11(v)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1596 | })); | 
|  | 1597 | } | 
|  | 1598 | TEST_F(HidlTest, PointerGiveArrayRefTest) { | 
|  | 1599 | EXPECT_OK(pointerInterface->bar12([&](const auto& array) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1600 | EXPECT_OK(validationPointerInterface->foo12(array)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1601 | })); | 
|  | 1602 | } | 
|  | 1603 | TEST_F(HidlTest, PointerGiveRefArrayTest) { | 
|  | 1604 | EXPECT_OK(pointerInterface->bar13([&](const auto& array) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1605 | EXPECT_OK(validationPointerInterface->foo13(array)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1606 | })); | 
|  | 1607 | } | 
|  | 1608 | TEST_F(HidlTest, PointerGive3RefTest) { | 
|  | 1609 | EXPECT_OK(pointerInterface->bar14([&](const auto& p3) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1610 | EXPECT_OK(validationPointerInterface->foo14(p3)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1611 | })); | 
|  | 1612 | } | 
|  | 1613 | TEST_F(HidlTest, PointerGiveInt3RefTest) { | 
|  | 1614 | EXPECT_OK(pointerInterface->bar15([&](const auto& p3) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1615 | EXPECT_OK(validationPointerInterface->foo15(p3)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1616 | })); | 
|  | 1617 | } | 
|  | 1618 | TEST_F(HidlTest, PointerGiveEmbeddedPointersTest) { | 
|  | 1619 | EXPECT_OK(pointerInterface->bar16([&](const auto& p) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1620 | EXPECT_OK(validationPointerInterface->foo16(p)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1621 | })); | 
|  | 1622 | } | 
|  | 1623 | TEST_F(HidlTest, PointerGiveEmbeddedPointers2Test) { | 
|  | 1624 | EXPECT_OK(pointerInterface->bar17([&](const auto& p) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1625 | EXPECT_OK(validationPointerInterface->foo17(p)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1626 | })); | 
|  | 1627 | } | 
|  | 1628 | TEST_F(HidlTest, PointerGiveCopiedStringTest) { | 
|  | 1629 | EXPECT_OK(pointerInterface->bar18([&](const auto& str_ref, const auto& str_ref2, const auto& str) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1630 | EXPECT_OK(validationPointerInterface->foo18(str_ref, str_ref2, str)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1631 | })); | 
|  | 1632 | } | 
|  | 1633 | TEST_F(HidlTest, PointerGiveCopiedVecTest) { | 
|  | 1634 | EXPECT_OK(pointerInterface->bar19([&](const auto& a_vec_ref, const auto& a_vec, const auto& a_vec_ref2) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1635 | EXPECT_OK(validationPointerInterface->foo19(a_vec_ref, a_vec, a_vec_ref2)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1636 | })); | 
|  | 1637 | } | 
| Yifan Hong | 8446590 | 2016-09-27 15:52:17 -0700 | [diff] [blame] | 1638 | // This cannot be enabled until _hidl_error is not ignored when | 
|  | 1639 | // the remote writeEmbeddedReferencesToParcel. | 
|  | 1640 | // TEST_F(HidlTest, PointerGiveBigRefVecTest) { | 
|  | 1641 | //     EXPECT_FAIL(pointerInterface->bar20([&](const auto& v) { | 
|  | 1642 | //     })); | 
|  | 1643 | // } | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1644 | TEST_F(HidlTest, PointerGiveMultidimArrayRefTest) { | 
|  | 1645 | EXPECT_OK(pointerInterface->bar21([&](const auto& v) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1646 | EXPECT_OK(validationPointerInterface->foo21(v)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1647 | })); | 
|  | 1648 | } | 
|  | 1649 | TEST_F(HidlTest, PointerGiveRefMultidimArrayTest) { | 
|  | 1650 | EXPECT_OK(pointerInterface->bar22([&](const auto& v) { | 
| Yifan Hong | 3cccc0f | 2016-10-13 10:12:28 -0700 | [diff] [blame] | 1651 | EXPECT_OK(validationPointerInterface->foo22(v)); | 
| Yifan Hong | bf459bc | 2016-08-23 16:50:37 -0700 | [diff] [blame] | 1652 | })); | 
|  | 1653 | } | 
|  | 1654 | TEST_F(HidlTest, PointerReportErrorsTest) { | 
|  | 1655 | Return<int32_t> ret = pointerInterface->getErrors(); | 
|  | 1656 | EXPECT_OK(ret); | 
|  | 1657 | EXPECT_EQ(int32_t(ret), 0); | 
|  | 1658 | } | 
|  | 1659 | #endif | 
|  | 1660 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1661 | int forkAndRunTests(TestMode mode) { | 
|  | 1662 | pid_t child; | 
|  | 1663 | int status; | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 1664 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1665 | const char* modeText = (mode == BINDERIZED) ? "BINDERIZED" : "PASSTHROUGH"; | 
|  | 1666 | ALOGI("Start running tests in %s mode...", modeText); | 
|  | 1667 | fprintf(stdout, "Start running tests in %s mode...\n", modeText); | 
|  | 1668 | fflush(stdout); | 
|  | 1669 |  | 
|  | 1670 | if ((child = fork()) == 0) { | 
|  | 1671 | gMode = mode; | 
|  | 1672 | if (gMode == PASSTHROUGH) { | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 1673 | gPassthroughEnvironment = static_cast<PassthroughEnvironment *>( | 
|  | 1674 | ::testing::AddGlobalTestEnvironment(new PassthroughEnvironment)); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1675 | } else if (gMode == BINDERIZED) { | 
| Yifan Hong | ca89052 | 2016-10-12 10:03:41 -0700 | [diff] [blame] | 1676 | gBinderizedEnvironment = static_cast<BinderizedEnvironment *>( | 
|  | 1677 | ::testing::AddGlobalTestEnvironment(new BinderizedEnvironment)); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1678 | } | 
|  | 1679 | int testStatus = RUN_ALL_TESTS(); | 
|  | 1680 | if(testStatus == 0) { | 
|  | 1681 | exit(0); | 
|  | 1682 | } | 
|  | 1683 | int failed = ::testing::UnitTest::GetInstance()->failed_test_count(); | 
|  | 1684 | if (failed == 0) { | 
|  | 1685 | exit(-testStatus); | 
|  | 1686 | } | 
|  | 1687 | exit(failed); | 
|  | 1688 | } | 
|  | 1689 | waitpid(child, &status, 0 /* options */); | 
|  | 1690 | ALOGI("All tests finished in %s mode.", modeText); | 
|  | 1691 | fprintf(stdout, "All tests finished in %s mode.\n", modeText); | 
|  | 1692 | fflush(stdout); | 
| Yifan Hong | 1dc8793 | 2016-08-19 09:51:01 -0700 | [diff] [blame] | 1693 | return status; | 
| Andreas Huber | 9cd48d0 | 2016-08-03 14:25:59 -0700 | [diff] [blame] | 1694 | } | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1695 |  | 
|  | 1696 | void handleStatus(int status, const char *mode) { | 
|  | 1697 | if (status != 0) { | 
|  | 1698 | if (WIFEXITED(status)) { | 
|  | 1699 | status = WEXITSTATUS(status); | 
|  | 1700 | if (status < 0) { | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1701 | fprintf(stdout, "    RUN_ALL_TESTS returns %d for %s mode.\n", -status, mode); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1702 | } else { | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1703 | fprintf(stdout, "    %d test(s) failed for %s mode.\n", status, mode); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1704 | } | 
|  | 1705 | } else { | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1706 | fprintf(stdout, "    ERROR: %s child process exited abnormally with %d\n", mode, status); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1707 | } | 
|  | 1708 | } | 
|  | 1709 | } | 
|  | 1710 |  | 
| Yifan Hong | d12398d | 2016-10-13 11:05:29 -0700 | [diff] [blame] | 1711 | static void usage(const char *me) { | 
|  | 1712 | fprintf(stderr, | 
|  | 1713 | "usage: %s [-b] [-p] [GTEST_OPTIONS]\n", | 
|  | 1714 | me); | 
|  | 1715 |  | 
|  | 1716 | fprintf(stderr, "         -b binderized mode only\n"); | 
|  | 1717 | fprintf(stderr, "         -p passthrough mode only\n"); | 
|  | 1718 | fprintf(stderr, "            (if -b and -p are both missing or both present, " | 
|  | 1719 | "both modes are tested.)\n"); | 
|  | 1720 | } | 
|  | 1721 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1722 | int main(int argc, char **argv) { | 
| Yifan Hong | d12398d | 2016-10-13 11:05:29 -0700 | [diff] [blame] | 1723 | const char *me = argv[0]; | 
|  | 1724 | bool b = false; | 
|  | 1725 | bool p = false; | 
|  | 1726 | struct option longopts[] = {{0,0,0,0}}; | 
|  | 1727 | int res; | 
|  | 1728 | while ((res = getopt_long(argc, argv, "hbp", longopts, NULL)) >= 0) { | 
|  | 1729 | switch (res) { | 
|  | 1730 | case 'h': { | 
|  | 1731 | usage(me); | 
|  | 1732 | exit(1); | 
|  | 1733 | } break; | 
|  | 1734 |  | 
|  | 1735 | case 'b': { | 
|  | 1736 | b = true; | 
|  | 1737 | } break; | 
|  | 1738 |  | 
|  | 1739 | case 'p': { | 
|  | 1740 | p = true; | 
|  | 1741 | } break; | 
|  | 1742 |  | 
|  | 1743 | case '?': | 
|  | 1744 | default: { | 
|  | 1745 | // ignore. pass to gTest. | 
|  | 1746 | } break; | 
|  | 1747 | } | 
|  | 1748 | } | 
|  | 1749 | if (!b && !p) { | 
|  | 1750 | b = p = true; | 
|  | 1751 | } | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1752 |  | 
|  | 1753 | ::testing::InitGoogleTest(&argc, argv); | 
|  | 1754 | // put test in child process because RUN_ALL_TESTS | 
|  | 1755 | // should not be run twice. | 
| Yifan Hong | d12398d | 2016-10-13 11:05:29 -0700 | [diff] [blame] | 1756 | int pStatus = p ? forkAndRunTests(PASSTHROUGH) : 0; | 
|  | 1757 | int bStatus = b ? forkAndRunTests(BINDERIZED)  : 0; | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1758 |  | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1759 | fprintf(stdout, "\n=========================================================\n\n" | 
|  | 1760 | "    Summary:\n\n"); | 
| Yifan Hong | d12398d | 2016-10-13 11:05:29 -0700 | [diff] [blame] | 1761 | if (p) { | 
|  | 1762 | ALOGI("PASSTHROUGH Test result = %d", pStatus); | 
|  | 1763 | handleStatus(pStatus, "PASSTHROUGH"); | 
|  | 1764 | } | 
|  | 1765 | if (b) { | 
|  | 1766 | ALOGI("BINDERIZED Test result = %d", bStatus); | 
|  | 1767 | handleStatus(bStatus, "BINDERIZED "); | 
|  | 1768 | } | 
|  | 1769 |  | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1770 | if (pStatus == 0 && bStatus == 0) { | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1771 | fprintf(stdout, "    Hooray! All tests passed.\n"); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1772 | } | 
| Yifan Hong | 48562fd | 2016-10-24 15:26:10 -0700 | [diff] [blame] | 1773 | fprintf(stdout, "\n=========================================================\n\n"); | 
| Yifan Hong | c70f0d8 | 2016-10-10 14:50:22 -0700 | [diff] [blame] | 1774 |  | 
|  | 1775 | return pStatus + bStatus; | 
|  | 1776 | } |