1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <errno.h> 18 #include <fcntl.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 22 #include <gtest/gtest.h> 23 #include <linux/binder.h> 24 #include <binder/IBinder.h> 25 #include <sys/mman.h> 26 #include <poll.h> 27 28 #define BINDER_DEV_NAME "/dev/binder" 29 30 testing::Environment* binder_env; 31 32 class BinderDriverInterfaceTestEnv : public ::testing::Environment { 33 virtual void SetUp() { 34 int ret; 35 uint32_t max_threads = 0; 36 37 m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC); 38 ASSERT_GE(m_binderFd, 0); 39 m_buffer = mmap(NULL, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0); 40 ASSERT_NE(m_buffer, (void *)NULL); 41 ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads); 42 EXPECT_EQ(0, ret); 43 EnterLooper(); 44 } 45 virtual void TearDown() { 46 close(m_binderFd); 47 } 48 private: 49 int m_binderFd; 50 void *m_buffer; 51 public: 52 int getBinderFd(void) { 53 return m_binderFd; 54 } 55 void EnterLooper(void) { 56 int ret; 57 const uint32_t bc[] = { 58 BC_ENTER_LOOPER, 59 }; 60 struct binder_write_read bwr = binder_write_read(); 61 bwr.write_buffer = (uintptr_t)bc; 62 bwr.write_size = sizeof(bc); 63 ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr); 64 EXPECT_EQ(0, ret); 65 if (ret < 0) { 66 EXPECT_EQ(0, errno); 67 } 68 EXPECT_EQ(sizeof(bc), bwr.write_consumed); 69 } 70 }; 71 72 class BinderDriverInterfaceTest : public ::testing::Test { 73 public: 74 virtual void SetUp() { 75 m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd(); 76 } 77 virtual void TearDown() { 78 } 79 protected: 80 void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) { 81 int ret; 82 83 ret = ioctl(m_binderFd, cmd, arg); 84 EXPECT_EQ(expect_ret, ret); 85 if (ret < 0) { 86 if (errno != accept_errno) 87 EXPECT_EQ(expect_errno, errno); 88 } 89 } 90 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) { 91 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno); 92 } 93 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) { 94 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno); 95 } 96 void binderTestIoctl(int cmd, void *arg) { 97 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0); 98 } 99 void binderTestIoctlUnimplemented(int cmd, void *arg) { 100 int ret; 101 102 ret = ioctl(m_binderFd, cmd, arg); 103 if (ret < 0) { 104 /* Not currently implmented. Allow ret == -1, errno == EINVAL */ 105 EXPECT_EQ(-1, ret); 106 EXPECT_EQ(EINVAL, errno); 107 } 108 } 109 void binderTestReadEmpty(void) { 110 size_t i; 111 uint32_t br[32]; 112 struct binder_write_read bwr = binder_write_read(); 113 SCOPED_TRACE("TestReadEmpty"); 114 bwr.read_buffer = (uintptr_t)br; 115 bwr.read_size = sizeof(br); 116 binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN); 117 EXPECT_EQ(0u, bwr.read_consumed); 118 for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) { 119 SCOPED_TRACE(testing::Message() << "i = " << i); 120 EXPECT_EQ(BR_NOOP, br[i]); 121 } 122 } 123 void binderWaitForReadData(int timeout_ms) { 124 int ret; 125 pollfd pfd = pollfd(); 126 127 pfd.fd = m_binderFd; 128 pfd.events = POLLIN; 129 ret = poll(&pfd, 1, timeout_ms); 130 EXPECT_EQ(1, ret); 131 } 132 private: 133 int m_binderFd; 134 }; 135 136 TEST_F(BinderDriverInterfaceTest, Version) { 137 struct binder_version version; 138 binderTestIoctl(BINDER_VERSION, &version); 139 ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version); 140 } 141 142 TEST_F(BinderDriverInterfaceTest, WriteReadNull) { 143 binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT); 144 } 145 146 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) { 147 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL); 148 } 149 150 TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) { 151 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */ 152 } 153 154 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) { 155 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL); 156 } 157 158 TEST_F(BinderDriverInterfaceTest, VersionNull) { 159 binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */ 160 } 161 162 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) { 163 int64_t idle_timeout = 100000; 164 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout); 165 } 166 167 TEST_F(BinderDriverInterfaceTest, SetMaxThreads) { 168 uint32_t max_threads = 0; 169 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads); 170 } 171 172 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) { 173 int idle_priority = 0; 174 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority); 175 } 176 177 TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) { 178 int32_t dummy = 0; 179 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY); 180 } 181 182 TEST_F(BinderDriverInterfaceTest, ThreadExit) { 183 int32_t dummy = 0; 184 binderTestIoctl(BINDER_THREAD_EXIT, &dummy); 185 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper(); 186 } 187 188 TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) { 189 struct binder_write_read bwr = binder_write_read(); 190 binderTestIoctl(BINDER_WRITE_READ, &bwr); 191 } 192 193 TEST_F(BinderDriverInterfaceTest, Read) { 194 binderTestReadEmpty(); 195 } 196 197 TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) { 198 const uint32_t bc[] = { 199 BC_INCREFS, 200 0, 201 BC_ACQUIRE, 202 0, 203 BC_RELEASE, 204 0, 205 BC_DECREFS, 206 0, 207 }; 208 struct binder_write_read bwr = binder_write_read(); 209 bwr.write_buffer = (uintptr_t)bc; 210 bwr.write_size = sizeof(bc); 211 binderTestIoctl(BINDER_WRITE_READ, &bwr); 212 EXPECT_EQ(sizeof(bc), bwr.write_consumed); 213 binderTestReadEmpty(); 214 } 215 216 TEST_F(BinderDriverInterfaceTest, Transaction) { 217 binder_uintptr_t cookie = 1234; 218 struct { 219 uint32_t cmd1; 220 struct binder_transaction_data arg1; 221 } __attribute__((packed)) bc1 = { 222 .cmd1 = BC_TRANSACTION, 223 .arg1 = { 224 .target = { 0 }, 225 .cookie = 0, 226 .code = android::IBinder::PING_TRANSACTION, 227 .flags = 0, 228 .sender_pid = 0, 229 .sender_euid = 0, 230 .data_size = 0, 231 .offsets_size = 0, 232 .data = {0, 0}, 233 }, 234 }; 235 struct { 236 uint32_t cmd0; 237 uint32_t cmd1; 238 uint32_t cmd2; 239 binder_transaction_data arg2; 240 uint32_t pad[16]; 241 } __attribute__((packed)) br; 242 struct binder_write_read bwr = binder_write_read(); 243 244 bwr.write_buffer = (uintptr_t)&bc1; 245 bwr.write_size = sizeof(bc1); 246 bwr.read_buffer = (uintptr_t)&br; 247 bwr.read_size = sizeof(br); 248 249 { 250 SCOPED_TRACE("1st WriteRead"); 251 binderTestIoctl(BINDER_WRITE_READ, &bwr); 252 } 253 EXPECT_EQ(sizeof(bc1), bwr.write_consumed); 254 if (bwr.read_consumed < offsetof(typeof(br), pad)) { 255 SCOPED_TRACE("2nd WriteRead"); 256 binderWaitForReadData(10000); 257 binderTestIoctl(BINDER_WRITE_READ, &bwr); 258 } 259 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed); 260 if (bwr.read_consumed > offsetof(typeof(br), cmd0)) 261 EXPECT_EQ(BR_NOOP, br.cmd0); 262 if (bwr.read_consumed > offsetof(typeof(br), cmd1)) 263 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1); 264 if (bwr.read_consumed > offsetof(typeof(br), cmd2)) 265 EXPECT_EQ(BR_REPLY, br.cmd2); 266 if (bwr.read_consumed >= offsetof(typeof(br), pad)) { 267 EXPECT_EQ(0u, br.arg2.target.ptr); 268 EXPECT_EQ(0u, br.arg2.cookie); 269 EXPECT_EQ(0u, br.arg2.code); 270 EXPECT_EQ(0u, br.arg2.flags); 271 EXPECT_EQ(0u, br.arg2.data_size); 272 EXPECT_EQ(0u, br.arg2.offsets_size); 273 274 SCOPED_TRACE("3rd WriteRead"); 275 276 binderTestReadEmpty(); 277 278 struct { 279 uint32_t cmd1; 280 binder_uintptr_t arg1; 281 } __attribute__((packed)) bc2 = { 282 .cmd1 = BC_FREE_BUFFER, 283 .arg1 = br.arg2.data.ptr.buffer, 284 }; 285 286 bwr.write_buffer = (uintptr_t)&bc2; 287 bwr.write_size = sizeof(bc2); 288 bwr.write_consumed = 0; 289 bwr.read_size = 0; 290 291 binderTestIoctl(BINDER_WRITE_READ, &bwr); 292 EXPECT_EQ(sizeof(bc2), bwr.write_consumed); 293 } 294 binderTestReadEmpty(); 295 } 296 297 TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) { 298 binder_uintptr_t cookie = 1234; 299 struct { 300 uint32_t cmd0; 301 uint32_t arg0; 302 uint32_t cmd1; 303 struct binder_handle_cookie arg1; 304 uint32_t cmd2; 305 struct binder_handle_cookie arg2; 306 uint32_t cmd3; 307 uint32_t arg3; 308 } __attribute__((packed)) bc = { 309 .cmd0 = BC_INCREFS, 310 .arg0 = 0, 311 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION, 312 .arg1 = { 313 .handle = 0, 314 .cookie = cookie, 315 }, 316 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION, 317 .arg2 = { 318 .handle = 0, 319 .cookie = cookie, 320 }, 321 .cmd3 = BC_DECREFS, 322 .arg3 = 0, 323 }; 324 struct { 325 uint32_t cmd0; 326 uint32_t cmd1; 327 binder_uintptr_t arg1; 328 uint32_t pad[16]; 329 } __attribute__((packed)) br; 330 struct binder_write_read bwr = binder_write_read(); 331 332 bwr.write_buffer = (uintptr_t)&bc; 333 bwr.write_size = sizeof(bc); 334 bwr.read_buffer = (uintptr_t)&br; 335 bwr.read_size = sizeof(br); 336 337 binderTestIoctl(BINDER_WRITE_READ, &bwr); 338 EXPECT_EQ(sizeof(bc), bwr.write_consumed); 339 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed); 340 EXPECT_EQ(BR_NOOP, br.cmd0); 341 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1); 342 EXPECT_EQ(cookie, br.arg1); 343 binderTestReadEmpty(); 344 } 345 346 int main(int argc, char **argv) { 347 ::testing::InitGoogleTest(&argc, argv); 348 349 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv()); 350 351 return RUN_ALL_TESTS(); 352 } 353 354