blob: af8286008f4f91012e4a630f6dd38d887543c3d8 [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
Tomasz Wasilczykb70f4712024-06-21 11:58:54 -070022#include <binder/IBinder.h>
Yu-Ting Tsengd5fc4462024-04-30 15:07:13 -070023#include <binder/ProcessState.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080024#include <gtest/gtest.h>
Dan Willemsene05dc6d2016-07-25 17:13:45 -070025#include <linux/android/binder.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080026#include <poll.h>
Tomasz Wasilczykb70f4712024-06-21 11:58:54 -070027#include <sys/ioctl.h>
28#include <sys/mman.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080029
Yu-Ting Tsengd5fc4462024-04-30 15:07:13 -070030#include "../binder_module.h"
31
Riley Andrewsdc9b1482014-12-18 11:54:32 -080032#define BINDER_DEV_NAME "/dev/binder"
33
34testing::Environment* binder_env;
35
36class BinderDriverInterfaceTestEnv : public ::testing::Environment {
37 virtual void SetUp() {
38 int ret;
39 uint32_t max_threads = 0;
40
Nick Kralevich0fe7ce32015-12-23 18:58:05 -080041 m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
Riley Andrewsdc9b1482014-12-18 11:54:32 -080042 ASSERT_GE(m_binderFd, 0);
Yi Kongfdd8da92018-06-07 17:52:27 -070043 m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
44 ASSERT_NE(m_buffer, (void *)nullptr);
Riley Andrewsdc9b1482014-12-18 11:54:32 -080045 ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
46 EXPECT_EQ(0, ret);
47 EnterLooper();
48 }
49 virtual void TearDown() {
50 close(m_binderFd);
51 }
52 private:
53 int m_binderFd;
54 void *m_buffer;
55 public:
56 int getBinderFd(void) {
57 return m_binderFd;
58 }
59 void EnterLooper(void) {
60 int ret;
61 const uint32_t bc[] = {
62 BC_ENTER_LOOPER,
63 };
64 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -080065 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -080066 bwr.write_size = sizeof(bc);
67 ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr);
68 EXPECT_EQ(0, ret);
69 if (ret < 0) {
70 EXPECT_EQ(0, errno);
71 }
72 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
73 }
74};
75
76class BinderDriverInterfaceTest : public ::testing::Test {
77 public:
78 virtual void SetUp() {
79 m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
80 }
81 virtual void TearDown() {
82 }
83 protected:
Martijn Coenen2b39df72017-12-11 11:10:34 +010084 /* The ioctl must either return 0, or if it doesn't errno should be accepted_errno */
85 void binderTestIoctlSuccessOrError(int cmd, void *arg, int accepted_errno) {
86 int ret;
87
88 ret = ioctl(m_binderFd, cmd, arg);
89 if (ret != 0) {
90 EXPECT_EQ(errno, accepted_errno);
91 }
92 }
93
Riley Andrewsdc9b1482014-12-18 11:54:32 -080094 void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
95 int ret;
96
97 ret = ioctl(m_binderFd, cmd, arg);
98 EXPECT_EQ(expect_ret, ret);
99 if (ret < 0) {
Tomasz Wasilczyk370408e2024-06-21 15:45:26 -0700100 if (errno != accept_errno) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800101 EXPECT_EQ(expect_errno, errno);
Tomasz Wasilczyk370408e2024-06-21 15:45:26 -0700102 }
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800103 }
104 }
105 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
106 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
107 }
108 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
109 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
110 }
111 void binderTestIoctl(int cmd, void *arg) {
112 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
113 }
114 void binderTestIoctlUnimplemented(int cmd, void *arg) {
115 int ret;
116
117 ret = ioctl(m_binderFd, cmd, arg);
118 if (ret < 0) {
119 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
120 EXPECT_EQ(-1, ret);
121 EXPECT_EQ(EINVAL, errno);
122 }
123 }
124 void binderTestReadEmpty(void) {
125 size_t i;
126 uint32_t br[32];
127 struct binder_write_read bwr = binder_write_read();
128 SCOPED_TRACE("TestReadEmpty");
Riley Andrews29d8cf92015-01-12 18:16:29 -0800129 bwr.read_buffer = (uintptr_t)br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800130 bwr.read_size = sizeof(br);
131 binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrews50bcb002015-01-12 18:14:55 -0800132 EXPECT_EQ(0u, bwr.read_consumed);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800133 for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
134 SCOPED_TRACE(testing::Message() << "i = " << i);
135 EXPECT_EQ(BR_NOOP, br[i]);
136 }
137 }
138 void binderWaitForReadData(int timeout_ms) {
139 int ret;
140 pollfd pfd = pollfd();
141
142 pfd.fd = m_binderFd;
143 pfd.events = POLLIN;
144 ret = poll(&pfd, 1, timeout_ms);
145 EXPECT_EQ(1, ret);
146 }
147 private:
148 int m_binderFd;
149};
150
151TEST_F(BinderDriverInterfaceTest, Version) {
152 struct binder_version version;
153 binderTestIoctl(BINDER_VERSION, &version);
154 ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
155}
156
Sherry Yang2437b322017-08-29 16:07:57 -0700157TEST_F(BinderDriverInterfaceTest, OpenNoMmap) {
158 int binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
159 ASSERT_GE(binderFd, 0);
160 close(binderFd);
161}
162
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800163TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700164 binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800165}
166
167TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700168 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800169}
170
171TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700172 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800173}
174
175TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700176 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800177}
178
179TEST_F(BinderDriverInterfaceTest, VersionNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700180 binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800181}
182
183TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
184 int64_t idle_timeout = 100000;
185 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
186}
187
188TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
189 uint32_t max_threads = 0;
190 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
191}
192
193TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
194 int idle_priority = 0;
195 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
196}
197
198TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
199 int32_t dummy = 0;
200 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
201}
202
203TEST_F(BinderDriverInterfaceTest, ThreadExit) {
204 int32_t dummy = 0;
205 binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
206 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
207}
208
209TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
210 struct binder_write_read bwr = binder_write_read();
211 binderTestIoctl(BINDER_WRITE_READ, &bwr);
212}
213
214TEST_F(BinderDriverInterfaceTest, Read) {
215 binderTestReadEmpty();
216}
217
218TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
219 const uint32_t bc[] = {
220 BC_INCREFS,
221 0,
222 BC_ACQUIRE,
223 0,
224 BC_RELEASE,
225 0,
226 BC_DECREFS,
227 0,
228 };
229 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -0800230 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800231 bwr.write_size = sizeof(bc);
232 binderTestIoctl(BINDER_WRITE_READ, &bwr);
233 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
234 binderTestReadEmpty();
235}
236
237TEST_F(BinderDriverInterfaceTest, Transaction) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800238 struct {
239 uint32_t cmd1;
240 struct binder_transaction_data arg1;
241 } __attribute__((packed)) bc1 = {
242 .cmd1 = BC_TRANSACTION,
243 .arg1 = {
244 .target = { 0 },
245 .cookie = 0,
246 .code = android::IBinder::PING_TRANSACTION,
247 .flags = 0,
248 .sender_pid = 0,
249 .sender_euid = 0,
250 .data_size = 0,
251 .offsets_size = 0,
Wei Wang78f2a372016-10-20 23:18:17 -0700252 .data = {
253 .ptr = {0, 0},
254 },
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800255 },
256 };
257 struct {
258 uint32_t cmd0;
259 uint32_t cmd1;
260 uint32_t cmd2;
261 binder_transaction_data arg2;
262 uint32_t pad[16];
263 } __attribute__((packed)) br;
264 struct binder_write_read bwr = binder_write_read();
265
Riley Andrews29d8cf92015-01-12 18:16:29 -0800266 bwr.write_buffer = (uintptr_t)&bc1;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800267 bwr.write_size = sizeof(bc1);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800268 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800269 bwr.read_size = sizeof(br);
270
271 {
272 SCOPED_TRACE("1st WriteRead");
Martijn Coenen2b39df72017-12-11 11:10:34 +0100273 binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800274 }
275 EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
276 if (bwr.read_consumed < offsetof(typeof(br), pad)) {
277 SCOPED_TRACE("2nd WriteRead");
278 binderWaitForReadData(10000);
279 binderTestIoctl(BINDER_WRITE_READ, &bwr);
280 }
281 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
Tomasz Wasilczyk370408e2024-06-21 15:45:26 -0700282 if (bwr.read_consumed > offsetof(typeof(br), cmd0)) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800283 EXPECT_EQ(BR_NOOP, br.cmd0);
Tomasz Wasilczyk370408e2024-06-21 15:45:26 -0700284 }
285 if (bwr.read_consumed > offsetof(typeof(br), cmd1)) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800286 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
Tomasz Wasilczyk370408e2024-06-21 15:45:26 -0700287 }
288 if (bwr.read_consumed > offsetof(typeof(br), cmd2)) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800289 EXPECT_EQ(BR_REPLY, br.cmd2);
Tomasz Wasilczyk370408e2024-06-21 15:45:26 -0700290 }
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800291 if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
Riley Andrews50bcb002015-01-12 18:14:55 -0800292 EXPECT_EQ(0u, br.arg2.target.ptr);
293 EXPECT_EQ(0u, br.arg2.cookie);
294 EXPECT_EQ(0u, br.arg2.code);
295 EXPECT_EQ(0u, br.arg2.flags);
Steven Moreland6e69d652019-07-10 14:17:55 -0700296 EXPECT_EQ(0u, br.arg2.data_size);
Riley Andrews50bcb002015-01-12 18:14:55 -0800297 EXPECT_EQ(0u, br.arg2.offsets_size);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800298
299 SCOPED_TRACE("3rd WriteRead");
300
301 binderTestReadEmpty();
302
303 struct {
304 uint32_t cmd1;
305 binder_uintptr_t arg1;
306 } __attribute__((packed)) bc2 = {
307 .cmd1 = BC_FREE_BUFFER,
308 .arg1 = br.arg2.data.ptr.buffer,
309 };
310
Riley Andrews29d8cf92015-01-12 18:16:29 -0800311 bwr.write_buffer = (uintptr_t)&bc2;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800312 bwr.write_size = sizeof(bc2);
313 bwr.write_consumed = 0;
314 bwr.read_size = 0;
315
316 binderTestIoctl(BINDER_WRITE_READ, &bwr);
317 EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
318 }
319 binderTestReadEmpty();
320}
321
322TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
323 binder_uintptr_t cookie = 1234;
324 struct {
325 uint32_t cmd0;
326 uint32_t arg0;
327 uint32_t cmd1;
328 struct binder_handle_cookie arg1;
329 uint32_t cmd2;
330 struct binder_handle_cookie arg2;
331 uint32_t cmd3;
332 uint32_t arg3;
333 } __attribute__((packed)) bc = {
334 .cmd0 = BC_INCREFS,
335 .arg0 = 0,
336 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
337 .arg1 = {
338 .handle = 0,
339 .cookie = cookie,
340 },
341 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
342 .arg2 = {
343 .handle = 0,
344 .cookie = cookie,
345 },
346 .cmd3 = BC_DECREFS,
347 .arg3 = 0,
348 };
349 struct {
350 uint32_t cmd0;
351 uint32_t cmd1;
352 binder_uintptr_t arg1;
353 uint32_t pad[16];
354 } __attribute__((packed)) br;
355 struct binder_write_read bwr = binder_write_read();
356
Riley Andrews29d8cf92015-01-12 18:16:29 -0800357 bwr.write_buffer = (uintptr_t)&bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800358 bwr.write_size = sizeof(bc);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800359 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800360 bwr.read_size = sizeof(br);
361
362 binderTestIoctl(BINDER_WRITE_READ, &bwr);
363 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
364 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
365 EXPECT_EQ(BR_NOOP, br.cmd0);
366 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
367 EXPECT_EQ(cookie, br.arg1);
368 binderTestReadEmpty();
369}
370
Yu-Ting Tsengd5fc4462024-04-30 15:07:13 -0700371TEST_F(BinderDriverInterfaceTest, RequestFrozenNotification) {
372 if (!android::ProcessState::isDriverFeatureEnabled(
373 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
374 GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
375 return;
376 }
377 binder_uintptr_t cookie = 1234;
378 struct {
379 uint32_t cmd0;
380 uint32_t arg0;
381 uint32_t cmd1;
382 struct binder_handle_cookie arg1;
383 } __attribute__((packed)) bc1 = {
384 .cmd0 = BC_INCREFS,
385 .arg0 = 0,
386 .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
387 .arg1 =
388 {
389 .handle = 0,
390 .cookie = cookie,
391 },
392 };
393 struct {
394 uint32_t cmd0;
395 // Expecting a BR_FROZEN_BINDER since BC_REQUEST_FREEZE_NOTIFICATION
396 // above should lead to an immediate notification of the current state.
397 uint32_t cmd1;
398 struct binder_frozen_state_info arg1;
399 uint32_t pad[16];
400 } __attribute__((packed)) br1;
401 struct {
402 uint32_t cmd2;
403 binder_uintptr_t arg2;
404 uint32_t cmd3;
405 struct binder_handle_cookie arg3;
406 uint32_t cmd4;
407 uint32_t arg4;
408 } __attribute__((packed)) bc2 = {
409 // Tell kernel that userspace has done handling BR_FROZEN_BINDER.
410 .cmd2 = BC_FREEZE_NOTIFICATION_DONE,
411 .arg2 = cookie,
412 .cmd3 = BC_CLEAR_FREEZE_NOTIFICATION,
413 .arg3 =
414 {
415 .handle = 0,
416 .cookie = cookie,
417 },
418 .cmd4 = BC_DECREFS,
419 .arg4 = 0,
420 };
421 struct {
422 uint32_t cmd2;
423 uint32_t cmd3;
424 binder_uintptr_t arg3;
425 uint32_t pad[16];
426 } __attribute__((packed)) br2;
427
428 struct binder_write_read bwr1 = binder_write_read();
429 bwr1.write_buffer = (uintptr_t)&bc1;
430 bwr1.write_size = sizeof(bc1);
431 bwr1.read_buffer = (uintptr_t)&br1;
432 bwr1.read_size = sizeof(br1);
433 binderTestIoctl(BINDER_WRITE_READ, &bwr1);
434 EXPECT_EQ(sizeof(bc1), bwr1.write_consumed);
435 EXPECT_EQ(sizeof(br1) - sizeof(br1.pad), bwr1.read_consumed);
436 EXPECT_EQ(BR_NOOP, br1.cmd0);
437 ASSERT_EQ(BR_FROZEN_BINDER, br1.cmd1);
438 EXPECT_FALSE(br1.arg1.is_frozen);
439
440 struct binder_write_read bwr2 = binder_write_read();
441 bwr2.write_buffer = (uintptr_t)&bc2;
442 bwr2.write_size = sizeof(bc2);
443 bwr2.read_buffer = (uintptr_t)&br2;
444 bwr2.read_size = sizeof(br2);
445 binderTestIoctl(BINDER_WRITE_READ, &bwr2);
446 EXPECT_EQ(sizeof(bc2), bwr2.write_consumed);
447 EXPECT_EQ(sizeof(br2) - sizeof(br2.pad), bwr2.read_consumed);
448 EXPECT_EQ(BR_NOOP, br2.cmd2);
449 EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br2.cmd3);
450 EXPECT_EQ(cookie, br2.arg3);
451
452 binderTestReadEmpty();
453}
454
455TEST_F(BinderDriverInterfaceTest, OverwritePendingFrozenNotification) {
456 if (!android::ProcessState::isDriverFeatureEnabled(
457 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
458 GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
459 return;
460 }
461 binder_uintptr_t cookie = 1234;
462 struct {
463 uint32_t cmd0;
464 uint32_t arg0;
465 uint32_t cmd1;
466 struct binder_handle_cookie arg1;
467 uint32_t cmd2;
468 struct binder_handle_cookie arg2;
469 uint32_t cmd3;
470 uint32_t arg3;
471 } __attribute__((packed)) bc = {
472 .cmd0 = BC_INCREFS,
473 .arg0 = 0,
474 .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
475 // This BC_REQUEST_FREEZE_NOTIFICATION should lead to a pending
476 // frozen notification inserted into the queue.
477 .arg1 =
478 {
479 .handle = 0,
480 .cookie = cookie,
481 },
482 // Send BC_CLEAR_FREEZE_NOTIFICATION before the above frozen
483 // notification has a chance of being sent. The notification should
484 // be overwritten. Userspace is expected to only receive
485 // BR_CLEAR_FREEZE_NOTIFICATION_DONE.
486 .cmd2 = BC_CLEAR_FREEZE_NOTIFICATION,
487 .arg2 =
488 {
489 .handle = 0,
490 .cookie = cookie,
491 },
492 .cmd3 = BC_DECREFS,
493 .arg3 = 0,
494 };
495 struct {
496 uint32_t cmd0;
497 uint32_t cmd1;
498 binder_uintptr_t arg1;
499 uint32_t pad[16];
500 } __attribute__((packed)) br;
501 struct binder_write_read bwr = binder_write_read();
502
503 bwr.write_buffer = (uintptr_t)&bc;
504 bwr.write_size = sizeof(bc);
505 bwr.read_buffer = (uintptr_t)&br;
506 bwr.read_size = sizeof(br);
507
508 binderTestIoctl(BINDER_WRITE_READ, &bwr);
509 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
510 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
511 EXPECT_EQ(BR_NOOP, br.cmd0);
512 EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br.cmd1);
513 EXPECT_EQ(cookie, br.arg1);
514 binderTestReadEmpty();
515}
516
517TEST_F(BinderDriverInterfaceTest, ResendFrozenNotification) {
518 if (!android::ProcessState::isDriverFeatureEnabled(
519 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
520 GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
521 return;
522 }
523 binder_uintptr_t cookie = 1234;
524 struct {
525 uint32_t cmd0;
526 uint32_t arg0;
527 uint32_t cmd1;
528 struct binder_handle_cookie arg1;
529 } __attribute__((packed)) bc1 = {
530 .cmd0 = BC_INCREFS,
531 .arg0 = 0,
532 .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
533 .arg1 =
534 {
535 .handle = 0,
536 .cookie = cookie,
537 },
538 };
539 struct {
540 uint32_t cmd0;
541 uint32_t cmd1;
542 struct binder_frozen_state_info arg1;
543 uint32_t pad[16];
544 } __attribute__((packed)) br1;
545 struct {
546 uint32_t cmd2;
547 struct binder_handle_cookie arg2;
548 } __attribute__((packed)) bc2 = {
549 // Clear the notification before acknowledging the in-flight
550 // BR_FROZEN_BINDER. Kernel should hold off sending
551 // BR_CLEAR_FREEZE_NOTIFICATION_DONE until the acknowledgement
552 // reaches kernel.
553 .cmd2 = BC_CLEAR_FREEZE_NOTIFICATION,
554 .arg2 =
555 {
556 .handle = 0,
557 .cookie = cookie,
558 },
559 };
560 struct {
561 uint32_t pad[16];
562 } __attribute__((packed)) br2;
563 struct {
564 uint32_t cmd3;
565 binder_uintptr_t arg3;
566 uint32_t cmd4;
567 uint32_t arg4;
568 } __attribute__((packed)) bc3 = {
569 // Send the acknowledgement. Now the kernel should send out
570 // BR_CLEAR_FREEZE_NOTIFICATION_DONE.
571 .cmd3 = BC_FREEZE_NOTIFICATION_DONE,
572 .arg3 = cookie,
573 .cmd4 = BC_DECREFS,
574 .arg4 = 0,
575 };
576 struct {
577 uint32_t cmd2;
578 uint32_t cmd3;
579 binder_uintptr_t arg3;
580 uint32_t pad[16];
581 } __attribute__((packed)) br3;
582
583 struct binder_write_read bwr1 = binder_write_read();
584 bwr1.write_buffer = (uintptr_t)&bc1;
585 bwr1.write_size = sizeof(bc1);
586 bwr1.read_buffer = (uintptr_t)&br1;
587 bwr1.read_size = sizeof(br1);
588 binderTestIoctl(BINDER_WRITE_READ, &bwr1);
589 EXPECT_EQ(sizeof(bc1), bwr1.write_consumed);
590 EXPECT_EQ(sizeof(br1) - sizeof(br1.pad), bwr1.read_consumed);
591 EXPECT_EQ(BR_NOOP, br1.cmd0);
592 ASSERT_EQ(BR_FROZEN_BINDER, br1.cmd1);
593 EXPECT_FALSE(br1.arg1.is_frozen);
594
595 struct binder_write_read bwr2 = binder_write_read();
596 bwr2.write_buffer = (uintptr_t)&bc2;
597 bwr2.write_size = sizeof(bc2);
598 bwr2.read_buffer = (uintptr_t)&br2;
599 bwr2.read_size = sizeof(br2);
600 binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr2, EAGAIN);
601 binderTestReadEmpty();
602
603 struct binder_write_read bwr3 = binder_write_read();
604 bwr3.write_buffer = (uintptr_t)&bc3;
605 bwr3.write_size = sizeof(bc3);
606 bwr3.read_buffer = (uintptr_t)&br3;
607 bwr3.read_size = sizeof(br3);
608 binderTestIoctl(BINDER_WRITE_READ, &bwr3);
609 EXPECT_EQ(sizeof(bc3), bwr3.write_consumed);
610 EXPECT_EQ(sizeof(br3) - sizeof(br3.pad), bwr3.read_consumed);
611 EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br3.cmd3);
612 EXPECT_EQ(cookie, br3.arg3);
613 binderTestReadEmpty();
614}
615
Steven Moreland68275d72023-04-21 22:12:45 +0000616int main(int argc, char** argv) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800617 ::testing::InitGoogleTest(&argc, argv);
618
619 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
620
621 return RUN_ALL_TESTS();
622}