blob: 3b5239fffa4cfffe70ba188c750a75d209f93ff2 [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) {
100 if (errno != accept_errno)
101 EXPECT_EQ(expect_errno, errno);
102 }
103 }
104 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
105 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
106 }
107 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
108 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
109 }
110 void binderTestIoctl(int cmd, void *arg) {
111 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
112 }
113 void binderTestIoctlUnimplemented(int cmd, void *arg) {
114 int ret;
115
116 ret = ioctl(m_binderFd, cmd, arg);
117 if (ret < 0) {
118 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
119 EXPECT_EQ(-1, ret);
120 EXPECT_EQ(EINVAL, errno);
121 }
122 }
123 void binderTestReadEmpty(void) {
124 size_t i;
125 uint32_t br[32];
126 struct binder_write_read bwr = binder_write_read();
127 SCOPED_TRACE("TestReadEmpty");
Riley Andrews29d8cf92015-01-12 18:16:29 -0800128 bwr.read_buffer = (uintptr_t)br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800129 bwr.read_size = sizeof(br);
130 binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrews50bcb002015-01-12 18:14:55 -0800131 EXPECT_EQ(0u, bwr.read_consumed);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800132 for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
133 SCOPED_TRACE(testing::Message() << "i = " << i);
134 EXPECT_EQ(BR_NOOP, br[i]);
135 }
136 }
137 void binderWaitForReadData(int timeout_ms) {
138 int ret;
139 pollfd pfd = pollfd();
140
141 pfd.fd = m_binderFd;
142 pfd.events = POLLIN;
143 ret = poll(&pfd, 1, timeout_ms);
144 EXPECT_EQ(1, ret);
145 }
146 private:
147 int m_binderFd;
148};
149
150TEST_F(BinderDriverInterfaceTest, Version) {
151 struct binder_version version;
152 binderTestIoctl(BINDER_VERSION, &version);
153 ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
154}
155
Sherry Yang2437b322017-08-29 16:07:57 -0700156TEST_F(BinderDriverInterfaceTest, OpenNoMmap) {
157 int binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
158 ASSERT_GE(binderFd, 0);
159 close(binderFd);
160}
161
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800162TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700163 binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800164}
165
166TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700167 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800168}
169
170TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700171 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800172}
173
174TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700175 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800176}
177
178TEST_F(BinderDriverInterfaceTest, VersionNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700179 binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800180}
181
182TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
183 int64_t idle_timeout = 100000;
184 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
185}
186
187TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
188 uint32_t max_threads = 0;
189 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
190}
191
192TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
193 int idle_priority = 0;
194 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
195}
196
197TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
198 int32_t dummy = 0;
199 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
200}
201
202TEST_F(BinderDriverInterfaceTest, ThreadExit) {
203 int32_t dummy = 0;
204 binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
205 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
206}
207
208TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
209 struct binder_write_read bwr = binder_write_read();
210 binderTestIoctl(BINDER_WRITE_READ, &bwr);
211}
212
213TEST_F(BinderDriverInterfaceTest, Read) {
214 binderTestReadEmpty();
215}
216
217TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
218 const uint32_t bc[] = {
219 BC_INCREFS,
220 0,
221 BC_ACQUIRE,
222 0,
223 BC_RELEASE,
224 0,
225 BC_DECREFS,
226 0,
227 };
228 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -0800229 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800230 bwr.write_size = sizeof(bc);
231 binderTestIoctl(BINDER_WRITE_READ, &bwr);
232 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
233 binderTestReadEmpty();
234}
235
236TEST_F(BinderDriverInterfaceTest, Transaction) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800237 struct {
238 uint32_t cmd1;
239 struct binder_transaction_data arg1;
240 } __attribute__((packed)) bc1 = {
241 .cmd1 = BC_TRANSACTION,
242 .arg1 = {
243 .target = { 0 },
244 .cookie = 0,
245 .code = android::IBinder::PING_TRANSACTION,
246 .flags = 0,
247 .sender_pid = 0,
248 .sender_euid = 0,
249 .data_size = 0,
250 .offsets_size = 0,
Wei Wang78f2a372016-10-20 23:18:17 -0700251 .data = {
252 .ptr = {0, 0},
253 },
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800254 },
255 };
256 struct {
257 uint32_t cmd0;
258 uint32_t cmd1;
259 uint32_t cmd2;
260 binder_transaction_data arg2;
261 uint32_t pad[16];
262 } __attribute__((packed)) br;
263 struct binder_write_read bwr = binder_write_read();
264
Riley Andrews29d8cf92015-01-12 18:16:29 -0800265 bwr.write_buffer = (uintptr_t)&bc1;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800266 bwr.write_size = sizeof(bc1);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800267 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800268 bwr.read_size = sizeof(br);
269
270 {
271 SCOPED_TRACE("1st WriteRead");
Martijn Coenen2b39df72017-12-11 11:10:34 +0100272 binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800273 }
274 EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
275 if (bwr.read_consumed < offsetof(typeof(br), pad)) {
276 SCOPED_TRACE("2nd WriteRead");
277 binderWaitForReadData(10000);
278 binderTestIoctl(BINDER_WRITE_READ, &bwr);
279 }
280 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
281 if (bwr.read_consumed > offsetof(typeof(br), cmd0))
282 EXPECT_EQ(BR_NOOP, br.cmd0);
283 if (bwr.read_consumed > offsetof(typeof(br), cmd1))
284 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
285 if (bwr.read_consumed > offsetof(typeof(br), cmd2))
286 EXPECT_EQ(BR_REPLY, br.cmd2);
287 if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
Riley Andrews50bcb002015-01-12 18:14:55 -0800288 EXPECT_EQ(0u, br.arg2.target.ptr);
289 EXPECT_EQ(0u, br.arg2.cookie);
290 EXPECT_EQ(0u, br.arg2.code);
291 EXPECT_EQ(0u, br.arg2.flags);
Steven Moreland6e69d652019-07-10 14:17:55 -0700292 EXPECT_EQ(0u, br.arg2.data_size);
Riley Andrews50bcb002015-01-12 18:14:55 -0800293 EXPECT_EQ(0u, br.arg2.offsets_size);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800294
295 SCOPED_TRACE("3rd WriteRead");
296
297 binderTestReadEmpty();
298
299 struct {
300 uint32_t cmd1;
301 binder_uintptr_t arg1;
302 } __attribute__((packed)) bc2 = {
303 .cmd1 = BC_FREE_BUFFER,
304 .arg1 = br.arg2.data.ptr.buffer,
305 };
306
Riley Andrews29d8cf92015-01-12 18:16:29 -0800307 bwr.write_buffer = (uintptr_t)&bc2;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800308 bwr.write_size = sizeof(bc2);
309 bwr.write_consumed = 0;
310 bwr.read_size = 0;
311
312 binderTestIoctl(BINDER_WRITE_READ, &bwr);
313 EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
314 }
315 binderTestReadEmpty();
316}
317
318TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
319 binder_uintptr_t cookie = 1234;
320 struct {
321 uint32_t cmd0;
322 uint32_t arg0;
323 uint32_t cmd1;
324 struct binder_handle_cookie arg1;
325 uint32_t cmd2;
326 struct binder_handle_cookie arg2;
327 uint32_t cmd3;
328 uint32_t arg3;
329 } __attribute__((packed)) bc = {
330 .cmd0 = BC_INCREFS,
331 .arg0 = 0,
332 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
333 .arg1 = {
334 .handle = 0,
335 .cookie = cookie,
336 },
337 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
338 .arg2 = {
339 .handle = 0,
340 .cookie = cookie,
341 },
342 .cmd3 = BC_DECREFS,
343 .arg3 = 0,
344 };
345 struct {
346 uint32_t cmd0;
347 uint32_t cmd1;
348 binder_uintptr_t arg1;
349 uint32_t pad[16];
350 } __attribute__((packed)) br;
351 struct binder_write_read bwr = binder_write_read();
352
Riley Andrews29d8cf92015-01-12 18:16:29 -0800353 bwr.write_buffer = (uintptr_t)&bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800354 bwr.write_size = sizeof(bc);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800355 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800356 bwr.read_size = sizeof(br);
357
358 binderTestIoctl(BINDER_WRITE_READ, &bwr);
359 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
360 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
361 EXPECT_EQ(BR_NOOP, br.cmd0);
362 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
363 EXPECT_EQ(cookie, br.arg1);
364 binderTestReadEmpty();
365}
366
Yu-Ting Tsengd5fc4462024-04-30 15:07:13 -0700367TEST_F(BinderDriverInterfaceTest, RequestFrozenNotification) {
368 if (!android::ProcessState::isDriverFeatureEnabled(
369 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
370 GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
371 return;
372 }
373 binder_uintptr_t cookie = 1234;
374 struct {
375 uint32_t cmd0;
376 uint32_t arg0;
377 uint32_t cmd1;
378 struct binder_handle_cookie arg1;
379 } __attribute__((packed)) bc1 = {
380 .cmd0 = BC_INCREFS,
381 .arg0 = 0,
382 .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
383 .arg1 =
384 {
385 .handle = 0,
386 .cookie = cookie,
387 },
388 };
389 struct {
390 uint32_t cmd0;
391 // Expecting a BR_FROZEN_BINDER since BC_REQUEST_FREEZE_NOTIFICATION
392 // above should lead to an immediate notification of the current state.
393 uint32_t cmd1;
394 struct binder_frozen_state_info arg1;
395 uint32_t pad[16];
396 } __attribute__((packed)) br1;
397 struct {
398 uint32_t cmd2;
399 binder_uintptr_t arg2;
400 uint32_t cmd3;
401 struct binder_handle_cookie arg3;
402 uint32_t cmd4;
403 uint32_t arg4;
404 } __attribute__((packed)) bc2 = {
405 // Tell kernel that userspace has done handling BR_FROZEN_BINDER.
406 .cmd2 = BC_FREEZE_NOTIFICATION_DONE,
407 .arg2 = cookie,
408 .cmd3 = BC_CLEAR_FREEZE_NOTIFICATION,
409 .arg3 =
410 {
411 .handle = 0,
412 .cookie = cookie,
413 },
414 .cmd4 = BC_DECREFS,
415 .arg4 = 0,
416 };
417 struct {
418 uint32_t cmd2;
419 uint32_t cmd3;
420 binder_uintptr_t arg3;
421 uint32_t pad[16];
422 } __attribute__((packed)) br2;
423
424 struct binder_write_read bwr1 = binder_write_read();
425 bwr1.write_buffer = (uintptr_t)&bc1;
426 bwr1.write_size = sizeof(bc1);
427 bwr1.read_buffer = (uintptr_t)&br1;
428 bwr1.read_size = sizeof(br1);
429 binderTestIoctl(BINDER_WRITE_READ, &bwr1);
430 EXPECT_EQ(sizeof(bc1), bwr1.write_consumed);
431 EXPECT_EQ(sizeof(br1) - sizeof(br1.pad), bwr1.read_consumed);
432 EXPECT_EQ(BR_NOOP, br1.cmd0);
433 ASSERT_EQ(BR_FROZEN_BINDER, br1.cmd1);
434 EXPECT_FALSE(br1.arg1.is_frozen);
435
436 struct binder_write_read bwr2 = binder_write_read();
437 bwr2.write_buffer = (uintptr_t)&bc2;
438 bwr2.write_size = sizeof(bc2);
439 bwr2.read_buffer = (uintptr_t)&br2;
440 bwr2.read_size = sizeof(br2);
441 binderTestIoctl(BINDER_WRITE_READ, &bwr2);
442 EXPECT_EQ(sizeof(bc2), bwr2.write_consumed);
443 EXPECT_EQ(sizeof(br2) - sizeof(br2.pad), bwr2.read_consumed);
444 EXPECT_EQ(BR_NOOP, br2.cmd2);
445 EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br2.cmd3);
446 EXPECT_EQ(cookie, br2.arg3);
447
448 binderTestReadEmpty();
449}
450
451TEST_F(BinderDriverInterfaceTest, OverwritePendingFrozenNotification) {
452 if (!android::ProcessState::isDriverFeatureEnabled(
453 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
454 GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
455 return;
456 }
457 binder_uintptr_t cookie = 1234;
458 struct {
459 uint32_t cmd0;
460 uint32_t arg0;
461 uint32_t cmd1;
462 struct binder_handle_cookie arg1;
463 uint32_t cmd2;
464 struct binder_handle_cookie arg2;
465 uint32_t cmd3;
466 uint32_t arg3;
467 } __attribute__((packed)) bc = {
468 .cmd0 = BC_INCREFS,
469 .arg0 = 0,
470 .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
471 // This BC_REQUEST_FREEZE_NOTIFICATION should lead to a pending
472 // frozen notification inserted into the queue.
473 .arg1 =
474 {
475 .handle = 0,
476 .cookie = cookie,
477 },
478 // Send BC_CLEAR_FREEZE_NOTIFICATION before the above frozen
479 // notification has a chance of being sent. The notification should
480 // be overwritten. Userspace is expected to only receive
481 // BR_CLEAR_FREEZE_NOTIFICATION_DONE.
482 .cmd2 = BC_CLEAR_FREEZE_NOTIFICATION,
483 .arg2 =
484 {
485 .handle = 0,
486 .cookie = cookie,
487 },
488 .cmd3 = BC_DECREFS,
489 .arg3 = 0,
490 };
491 struct {
492 uint32_t cmd0;
493 uint32_t cmd1;
494 binder_uintptr_t arg1;
495 uint32_t pad[16];
496 } __attribute__((packed)) br;
497 struct binder_write_read bwr = binder_write_read();
498
499 bwr.write_buffer = (uintptr_t)&bc;
500 bwr.write_size = sizeof(bc);
501 bwr.read_buffer = (uintptr_t)&br;
502 bwr.read_size = sizeof(br);
503
504 binderTestIoctl(BINDER_WRITE_READ, &bwr);
505 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
506 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
507 EXPECT_EQ(BR_NOOP, br.cmd0);
508 EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br.cmd1);
509 EXPECT_EQ(cookie, br.arg1);
510 binderTestReadEmpty();
511}
512
513TEST_F(BinderDriverInterfaceTest, ResendFrozenNotification) {
514 if (!android::ProcessState::isDriverFeatureEnabled(
515 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
516 GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
517 return;
518 }
519 binder_uintptr_t cookie = 1234;
520 struct {
521 uint32_t cmd0;
522 uint32_t arg0;
523 uint32_t cmd1;
524 struct binder_handle_cookie arg1;
525 } __attribute__((packed)) bc1 = {
526 .cmd0 = BC_INCREFS,
527 .arg0 = 0,
528 .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
529 .arg1 =
530 {
531 .handle = 0,
532 .cookie = cookie,
533 },
534 };
535 struct {
536 uint32_t cmd0;
537 uint32_t cmd1;
538 struct binder_frozen_state_info arg1;
539 uint32_t pad[16];
540 } __attribute__((packed)) br1;
541 struct {
542 uint32_t cmd2;
543 struct binder_handle_cookie arg2;
544 } __attribute__((packed)) bc2 = {
545 // Clear the notification before acknowledging the in-flight
546 // BR_FROZEN_BINDER. Kernel should hold off sending
547 // BR_CLEAR_FREEZE_NOTIFICATION_DONE until the acknowledgement
548 // reaches kernel.
549 .cmd2 = BC_CLEAR_FREEZE_NOTIFICATION,
550 .arg2 =
551 {
552 .handle = 0,
553 .cookie = cookie,
554 },
555 };
556 struct {
557 uint32_t pad[16];
558 } __attribute__((packed)) br2;
559 struct {
560 uint32_t cmd3;
561 binder_uintptr_t arg3;
562 uint32_t cmd4;
563 uint32_t arg4;
564 } __attribute__((packed)) bc3 = {
565 // Send the acknowledgement. Now the kernel should send out
566 // BR_CLEAR_FREEZE_NOTIFICATION_DONE.
567 .cmd3 = BC_FREEZE_NOTIFICATION_DONE,
568 .arg3 = cookie,
569 .cmd4 = BC_DECREFS,
570 .arg4 = 0,
571 };
572 struct {
573 uint32_t cmd2;
574 uint32_t cmd3;
575 binder_uintptr_t arg3;
576 uint32_t pad[16];
577 } __attribute__((packed)) br3;
578
579 struct binder_write_read bwr1 = binder_write_read();
580 bwr1.write_buffer = (uintptr_t)&bc1;
581 bwr1.write_size = sizeof(bc1);
582 bwr1.read_buffer = (uintptr_t)&br1;
583 bwr1.read_size = sizeof(br1);
584 binderTestIoctl(BINDER_WRITE_READ, &bwr1);
585 EXPECT_EQ(sizeof(bc1), bwr1.write_consumed);
586 EXPECT_EQ(sizeof(br1) - sizeof(br1.pad), bwr1.read_consumed);
587 EXPECT_EQ(BR_NOOP, br1.cmd0);
588 ASSERT_EQ(BR_FROZEN_BINDER, br1.cmd1);
589 EXPECT_FALSE(br1.arg1.is_frozen);
590
591 struct binder_write_read bwr2 = binder_write_read();
592 bwr2.write_buffer = (uintptr_t)&bc2;
593 bwr2.write_size = sizeof(bc2);
594 bwr2.read_buffer = (uintptr_t)&br2;
595 bwr2.read_size = sizeof(br2);
596 binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr2, EAGAIN);
597 binderTestReadEmpty();
598
599 struct binder_write_read bwr3 = binder_write_read();
600 bwr3.write_buffer = (uintptr_t)&bc3;
601 bwr3.write_size = sizeof(bc3);
602 bwr3.read_buffer = (uintptr_t)&br3;
603 bwr3.read_size = sizeof(br3);
604 binderTestIoctl(BINDER_WRITE_READ, &bwr3);
605 EXPECT_EQ(sizeof(bc3), bwr3.write_consumed);
606 EXPECT_EQ(sizeof(br3) - sizeof(br3.pad), bwr3.read_consumed);
607 EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br3.cmd3);
608 EXPECT_EQ(cookie, br3.arg3);
609 binderTestReadEmpty();
610}
611
Steven Moreland68275d72023-04-21 22:12:45 +0000612int main(int argc, char** argv) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800613 ::testing::InitGoogleTest(&argc, argv);
614
615 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
616
617 return RUN_ALL_TESTS();
618}