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/android/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 30testing::Environment* binder_env; 31 32class 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 72class 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 136TEST_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 142TEST_F(BinderDriverInterfaceTest, WriteReadNull) { 143 binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT); 144} 145 146TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) { 147 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL); 148} 149 150TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) { 151 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */ 152} 153 154TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) { 155 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL); 156} 157 158TEST_F(BinderDriverInterfaceTest, VersionNull) { 159 binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */ 160} 161 162TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) { 163 int64_t idle_timeout = 100000; 164 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout); 165} 166 167TEST_F(BinderDriverInterfaceTest, SetMaxThreads) { 168 uint32_t max_threads = 0; 169 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads); 170} 171 172TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) { 173 int idle_priority = 0; 174 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority); 175} 176 177TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) { 178 int32_t dummy = 0; 179 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY); 180} 181 182TEST_F(BinderDriverInterfaceTest, ThreadExit) { 183 int32_t dummy = 0; 184 binderTestIoctl(BINDER_THREAD_EXIT, &dummy); 185 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper(); 186} 187 188TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) { 189 struct binder_write_read bwr = binder_write_read(); 190 binderTestIoctl(BINDER_WRITE_READ, &bwr); 191} 192 193TEST_F(BinderDriverInterfaceTest, Read) { 194 binderTestReadEmpty(); 195} 196 197TEST_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 216TEST_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 = { 233 .ptr = {0, 0}, 234 }, 235 }, 236 }; 237 struct { 238 uint32_t cmd0; 239 uint32_t cmd1; 240 uint32_t cmd2; 241 binder_transaction_data arg2; 242 uint32_t pad[16]; 243 } __attribute__((packed)) br; 244 struct binder_write_read bwr = binder_write_read(); 245 246 bwr.write_buffer = (uintptr_t)&bc1; 247 bwr.write_size = sizeof(bc1); 248 bwr.read_buffer = (uintptr_t)&br; 249 bwr.read_size = sizeof(br); 250 251 { 252 SCOPED_TRACE("1st WriteRead"); 253 binderTestIoctl(BINDER_WRITE_READ, &bwr); 254 } 255 EXPECT_EQ(sizeof(bc1), bwr.write_consumed); 256 if (bwr.read_consumed < offsetof(typeof(br), pad)) { 257 SCOPED_TRACE("2nd WriteRead"); 258 binderWaitForReadData(10000); 259 binderTestIoctl(BINDER_WRITE_READ, &bwr); 260 } 261 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed); 262 if (bwr.read_consumed > offsetof(typeof(br), cmd0)) 263 EXPECT_EQ(BR_NOOP, br.cmd0); 264 if (bwr.read_consumed > offsetof(typeof(br), cmd1)) 265 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1); 266 if (bwr.read_consumed > offsetof(typeof(br), cmd2)) 267 EXPECT_EQ(BR_REPLY, br.cmd2); 268 if (bwr.read_consumed >= offsetof(typeof(br), pad)) { 269 EXPECT_EQ(0u, br.arg2.target.ptr); 270 EXPECT_EQ(0u, br.arg2.cookie); 271 EXPECT_EQ(0u, br.arg2.code); 272 EXPECT_EQ(0u, br.arg2.flags); 273 EXPECT_EQ(0u, br.arg2.data_size); 274 EXPECT_EQ(0u, br.arg2.offsets_size); 275 276 SCOPED_TRACE("3rd WriteRead"); 277 278 binderTestReadEmpty(); 279 280 struct { 281 uint32_t cmd1; 282 binder_uintptr_t arg1; 283 } __attribute__((packed)) bc2 = { 284 .cmd1 = BC_FREE_BUFFER, 285 .arg1 = br.arg2.data.ptr.buffer, 286 }; 287 288 bwr.write_buffer = (uintptr_t)&bc2; 289 bwr.write_size = sizeof(bc2); 290 bwr.write_consumed = 0; 291 bwr.read_size = 0; 292 293 binderTestIoctl(BINDER_WRITE_READ, &bwr); 294 EXPECT_EQ(sizeof(bc2), bwr.write_consumed); 295 } 296 binderTestReadEmpty(); 297} 298 299TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) { 300 binder_uintptr_t cookie = 1234; 301 struct { 302 uint32_t cmd0; 303 uint32_t arg0; 304 uint32_t cmd1; 305 struct binder_handle_cookie arg1; 306 uint32_t cmd2; 307 struct binder_handle_cookie arg2; 308 uint32_t cmd3; 309 uint32_t arg3; 310 } __attribute__((packed)) bc = { 311 .cmd0 = BC_INCREFS, 312 .arg0 = 0, 313 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION, 314 .arg1 = { 315 .handle = 0, 316 .cookie = cookie, 317 }, 318 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION, 319 .arg2 = { 320 .handle = 0, 321 .cookie = cookie, 322 }, 323 .cmd3 = BC_DECREFS, 324 .arg3 = 0, 325 }; 326 struct { 327 uint32_t cmd0; 328 uint32_t cmd1; 329 binder_uintptr_t arg1; 330 uint32_t pad[16]; 331 } __attribute__((packed)) br; 332 struct binder_write_read bwr = binder_write_read(); 333 334 bwr.write_buffer = (uintptr_t)&bc; 335 bwr.write_size = sizeof(bc); 336 bwr.read_buffer = (uintptr_t)&br; 337 bwr.read_size = sizeof(br); 338 339 binderTestIoctl(BINDER_WRITE_READ, &bwr); 340 EXPECT_EQ(sizeof(bc), bwr.write_consumed); 341 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed); 342 EXPECT_EQ(BR_NOOP, br.cmd0); 343 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1); 344 EXPECT_EQ(cookie, br.arg1); 345 binderTestReadEmpty(); 346} 347 348int main(int argc, char **argv) { 349 ::testing::InitGoogleTest(&argc, argv); 350 351 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv()); 352 353 return RUN_ALL_TESTS(); 354} 355