blob: 9b289c0c236dcfad775a8e9b786efce373af4017 [file] [log] [blame]
Riley Andrewsdc9b1482014-12-18 11:54:32 -08001/*
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>
Dan Willemsene05dc6d2016-07-25 17:13:45 -070023#include <linux/android/binder.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080024#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
Nick Kralevich0fe7ce32015-12-23 18:58:05 -080037 m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
Riley Andrewsdc9b1482014-12-18 11:54:32 -080038 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();
Riley Andrews29d8cf92015-01-12 18:16:29 -080061 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -080062 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:
Martijn Coenen380e74f2017-12-11 11:10:34 +010080 /* The ioctl must either return 0, or if it doesn't errno should be accepted_errno */
81 void binderTestIoctlSuccessOrError(int cmd, void *arg, int accepted_errno) {
82 int ret;
83
84 ret = ioctl(m_binderFd, cmd, arg);
85 if (ret != 0) {
86 EXPECT_EQ(errno, accepted_errno);
87 }
88 }
89
Riley Andrewsdc9b1482014-12-18 11:54:32 -080090 void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
91 int ret;
92
93 ret = ioctl(m_binderFd, cmd, arg);
94 EXPECT_EQ(expect_ret, ret);
95 if (ret < 0) {
96 if (errno != accept_errno)
97 EXPECT_EQ(expect_errno, errno);
98 }
99 }
100 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
101 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
102 }
103 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
104 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
105 }
106 void binderTestIoctl(int cmd, void *arg) {
107 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
108 }
109 void binderTestIoctlUnimplemented(int cmd, void *arg) {
110 int ret;
111
112 ret = ioctl(m_binderFd, cmd, arg);
113 if (ret < 0) {
114 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
115 EXPECT_EQ(-1, ret);
116 EXPECT_EQ(EINVAL, errno);
117 }
118 }
119 void binderTestReadEmpty(void) {
120 size_t i;
121 uint32_t br[32];
122 struct binder_write_read bwr = binder_write_read();
123 SCOPED_TRACE("TestReadEmpty");
Riley Andrews29d8cf92015-01-12 18:16:29 -0800124 bwr.read_buffer = (uintptr_t)br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800125 bwr.read_size = sizeof(br);
126 binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrews50bcb002015-01-12 18:14:55 -0800127 EXPECT_EQ(0u, bwr.read_consumed);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800128 for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
129 SCOPED_TRACE(testing::Message() << "i = " << i);
130 EXPECT_EQ(BR_NOOP, br[i]);
131 }
132 }
133 void binderWaitForReadData(int timeout_ms) {
134 int ret;
135 pollfd pfd = pollfd();
136
137 pfd.fd = m_binderFd;
138 pfd.events = POLLIN;
139 ret = poll(&pfd, 1, timeout_ms);
140 EXPECT_EQ(1, ret);
141 }
142 private:
143 int m_binderFd;
144};
145
146TEST_F(BinderDriverInterfaceTest, Version) {
147 struct binder_version version;
148 binderTestIoctl(BINDER_VERSION, &version);
149 ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
150}
151
152TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
153 binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT);
154}
155
156TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
157 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL);
158}
159
160TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
161 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
162}
163
164TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
165 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL);
166}
167
168TEST_F(BinderDriverInterfaceTest, VersionNull) {
169 binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
170}
171
172TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
173 int64_t idle_timeout = 100000;
174 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
175}
176
177TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
178 uint32_t max_threads = 0;
179 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
180}
181
182TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
183 int idle_priority = 0;
184 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
185}
186
187TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
188 int32_t dummy = 0;
189 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
190}
191
192TEST_F(BinderDriverInterfaceTest, ThreadExit) {
193 int32_t dummy = 0;
194 binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
195 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
196}
197
198TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
199 struct binder_write_read bwr = binder_write_read();
200 binderTestIoctl(BINDER_WRITE_READ, &bwr);
201}
202
203TEST_F(BinderDriverInterfaceTest, Read) {
204 binderTestReadEmpty();
205}
206
207TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
208 const uint32_t bc[] = {
209 BC_INCREFS,
210 0,
211 BC_ACQUIRE,
212 0,
213 BC_RELEASE,
214 0,
215 BC_DECREFS,
216 0,
217 };
218 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -0800219 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800220 bwr.write_size = sizeof(bc);
221 binderTestIoctl(BINDER_WRITE_READ, &bwr);
222 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
223 binderTestReadEmpty();
224}
225
226TEST_F(BinderDriverInterfaceTest, Transaction) {
227 binder_uintptr_t cookie = 1234;
228 struct {
229 uint32_t cmd1;
230 struct binder_transaction_data arg1;
231 } __attribute__((packed)) bc1 = {
232 .cmd1 = BC_TRANSACTION,
233 .arg1 = {
234 .target = { 0 },
235 .cookie = 0,
236 .code = android::IBinder::PING_TRANSACTION,
237 .flags = 0,
238 .sender_pid = 0,
239 .sender_euid = 0,
240 .data_size = 0,
241 .offsets_size = 0,
Wei Wang78f2a372016-10-20 23:18:17 -0700242 .data = {
243 .ptr = {0, 0},
244 },
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800245 },
246 };
247 struct {
248 uint32_t cmd0;
249 uint32_t cmd1;
250 uint32_t cmd2;
251 binder_transaction_data arg2;
252 uint32_t pad[16];
253 } __attribute__((packed)) br;
254 struct binder_write_read bwr = binder_write_read();
255
Riley Andrews29d8cf92015-01-12 18:16:29 -0800256 bwr.write_buffer = (uintptr_t)&bc1;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800257 bwr.write_size = sizeof(bc1);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800258 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800259 bwr.read_size = sizeof(br);
260
261 {
262 SCOPED_TRACE("1st WriteRead");
Martijn Coenen380e74f2017-12-11 11:10:34 +0100263 binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800264 }
265 EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
266 if (bwr.read_consumed < offsetof(typeof(br), pad)) {
267 SCOPED_TRACE("2nd WriteRead");
268 binderWaitForReadData(10000);
269 binderTestIoctl(BINDER_WRITE_READ, &bwr);
270 }
271 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
272 if (bwr.read_consumed > offsetof(typeof(br), cmd0))
273 EXPECT_EQ(BR_NOOP, br.cmd0);
274 if (bwr.read_consumed > offsetof(typeof(br), cmd1))
275 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
276 if (bwr.read_consumed > offsetof(typeof(br), cmd2))
277 EXPECT_EQ(BR_REPLY, br.cmd2);
278 if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
Riley Andrews50bcb002015-01-12 18:14:55 -0800279 EXPECT_EQ(0u, br.arg2.target.ptr);
280 EXPECT_EQ(0u, br.arg2.cookie);
281 EXPECT_EQ(0u, br.arg2.code);
282 EXPECT_EQ(0u, br.arg2.flags);
283 EXPECT_EQ(0u, br.arg2.data_size);
284 EXPECT_EQ(0u, br.arg2.offsets_size);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800285
286 SCOPED_TRACE("3rd WriteRead");
287
288 binderTestReadEmpty();
289
290 struct {
291 uint32_t cmd1;
292 binder_uintptr_t arg1;
293 } __attribute__((packed)) bc2 = {
294 .cmd1 = BC_FREE_BUFFER,
295 .arg1 = br.arg2.data.ptr.buffer,
296 };
297
Riley Andrews29d8cf92015-01-12 18:16:29 -0800298 bwr.write_buffer = (uintptr_t)&bc2;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800299 bwr.write_size = sizeof(bc2);
300 bwr.write_consumed = 0;
301 bwr.read_size = 0;
302
303 binderTestIoctl(BINDER_WRITE_READ, &bwr);
304 EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
305 }
306 binderTestReadEmpty();
307}
308
309TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
310 binder_uintptr_t cookie = 1234;
311 struct {
312 uint32_t cmd0;
313 uint32_t arg0;
314 uint32_t cmd1;
315 struct binder_handle_cookie arg1;
316 uint32_t cmd2;
317 struct binder_handle_cookie arg2;
318 uint32_t cmd3;
319 uint32_t arg3;
320 } __attribute__((packed)) bc = {
321 .cmd0 = BC_INCREFS,
322 .arg0 = 0,
323 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
324 .arg1 = {
325 .handle = 0,
326 .cookie = cookie,
327 },
328 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
329 .arg2 = {
330 .handle = 0,
331 .cookie = cookie,
332 },
333 .cmd3 = BC_DECREFS,
334 .arg3 = 0,
335 };
336 struct {
337 uint32_t cmd0;
338 uint32_t cmd1;
339 binder_uintptr_t arg1;
340 uint32_t pad[16];
341 } __attribute__((packed)) br;
342 struct binder_write_read bwr = binder_write_read();
343
Riley Andrews29d8cf92015-01-12 18:16:29 -0800344 bwr.write_buffer = (uintptr_t)&bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800345 bwr.write_size = sizeof(bc);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800346 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800347 bwr.read_size = sizeof(br);
348
349 binderTestIoctl(BINDER_WRITE_READ, &bwr);
350 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
351 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
352 EXPECT_EQ(BR_NOOP, br.cmd0);
353 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
354 EXPECT_EQ(cookie, br.arg1);
355 binderTestReadEmpty();
356}
357
358int main(int argc, char **argv) {
359 ::testing::InitGoogleTest(&argc, argv);
360
361 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
362
363 return RUN_ALL_TESTS();
364}