xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderDriverInterfaceTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 <binder/IBinder.h>
23 #include <binder/ProcessState.h>
24 #include <gtest/gtest.h>
25 #include <linux/android/binder.h>
26 #include <poll.h>
27 #include <sys/ioctl.h>
28 #include <sys/mman.h>
29 
30 #include "../binder_module.h"
31 
32 #define BINDER_DEV_NAME "/dev/binder"
33 
34 testing::Environment* binder_env;
35 
36 class BinderDriverInterfaceTestEnv : public ::testing::Environment {
SetUp()37         virtual void SetUp() {
38             int ret;
39             uint32_t max_threads = 0;
40 
41             m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
42             ASSERT_GE(m_binderFd, 0);
43             m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
44             ASSERT_NE(m_buffer, (void *)nullptr);
45             ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
46             EXPECT_EQ(0, ret);
47             EnterLooper();
48         }
TearDown()49         virtual void TearDown() {
50             close(m_binderFd);
51         }
52     private:
53         int m_binderFd;
54         void *m_buffer;
55     public:
getBinderFd(void)56         int getBinderFd(void) {
57             return m_binderFd;
58         }
EnterLooper(void)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();
65             bwr.write_buffer = (uintptr_t)bc;
66             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 
76 class BinderDriverInterfaceTest : public ::testing::Test {
77     public:
SetUp()78         virtual void SetUp() {
79             m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
80         }
TearDown()81         virtual void TearDown() {
82         }
83     protected:
84         /* The ioctl must either return 0, or if it doesn't errno should be accepted_errno */
binderTestIoctlSuccessOrError(int cmd,void * arg,int 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 
binderTestIoctlRetErr2(int cmd,void * arg,int expect_ret,int expect_errno,int accept_errno)94         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         }
binderTestIoctlErr2(int cmd,void * arg,int expect_errno,int accept_errno)105         void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
106             binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
107         }
binderTestIoctlErr1(int cmd,void * arg,int expect_errno)108         void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
109             binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
110         }
binderTestIoctl(int cmd,void * arg)111         void binderTestIoctl(int cmd, void *arg) {
112             binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
113         }
binderTestIoctlUnimplemented(int cmd,void * arg)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         }
binderTestReadEmpty(void)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");
129             bwr.read_buffer = (uintptr_t)br;
130             bwr.read_size = sizeof(br);
131             binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
132             EXPECT_EQ(0u, bwr.read_consumed);
133             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         }
binderWaitForReadData(int timeout_ms)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 
TEST_F(BinderDriverInterfaceTest,Version)151 TEST_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 
TEST_F(BinderDriverInterfaceTest,OpenNoMmap)157 TEST_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 
TEST_F(BinderDriverInterfaceTest,WriteReadNull)163 TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
164     binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
165 }
166 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNull)167 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
168     binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
169 }
170 
TEST_F(BinderDriverInterfaceTest,SetMaxThreadsNull)171 TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
172     binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
173 }
174 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNull)175 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
176     binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
177 }
178 
TEST_F(BinderDriverInterfaceTest,VersionNull)179 TEST_F(BinderDriverInterfaceTest, VersionNull) {
180     binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
181 }
182 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNoTest)183 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
184     int64_t idle_timeout = 100000;
185     binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
186 }
187 
TEST_F(BinderDriverInterfaceTest,SetMaxThreads)188 TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
189     uint32_t max_threads = 0;
190     binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
191 }
192 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNoTest)193 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
194     int idle_priority = 0;
195     binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
196 }
197 
TEST_F(BinderDriverInterfaceTest,SetContextMgrBusy)198 TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
199     int32_t dummy = 0;
200     binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
201 }
202 
TEST_F(BinderDriverInterfaceTest,ThreadExit)203 TEST_F(BinderDriverInterfaceTest, ThreadExit) {
204     int32_t dummy = 0;
205     binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
206     static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
207 }
208 
TEST_F(BinderDriverInterfaceTest,WriteReadEmpty)209 TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
210     struct binder_write_read bwr = binder_write_read();
211     binderTestIoctl(BINDER_WRITE_READ, &bwr);
212 }
213 
TEST_F(BinderDriverInterfaceTest,Read)214 TEST_F(BinderDriverInterfaceTest, Read) {
215     binderTestReadEmpty();
216 }
217 
TEST_F(BinderDriverInterfaceTest,IncRefsAcquireReleaseDecRefs)218 TEST_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();
230     bwr.write_buffer = (uintptr_t)bc;
231     bwr.write_size = sizeof(bc);
232     binderTestIoctl(BINDER_WRITE_READ, &bwr);
233     EXPECT_EQ(sizeof(bc), bwr.write_consumed);
234     binderTestReadEmpty();
235 }
236 
TEST_F(BinderDriverInterfaceTest,Transaction)237 TEST_F(BinderDriverInterfaceTest, Transaction) {
238     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,
252             .data = {
253                 .ptr = {0, 0},
254             },
255         },
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 
266     bwr.write_buffer = (uintptr_t)&bc1;
267     bwr.write_size = sizeof(bc1);
268     bwr.read_buffer = (uintptr_t)&br;
269     bwr.read_size = sizeof(br);
270 
271     {
272         SCOPED_TRACE("1st WriteRead");
273         binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
274     }
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);
282     if (bwr.read_consumed > offsetof(typeof(br), cmd0)) {
283         EXPECT_EQ(BR_NOOP, br.cmd0);
284     }
285     if (bwr.read_consumed > offsetof(typeof(br), cmd1)) {
286         EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
287     }
288     if (bwr.read_consumed > offsetof(typeof(br), cmd2)) {
289         EXPECT_EQ(BR_REPLY, br.cmd2);
290     }
291     if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
292         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);
296         EXPECT_EQ(0u, br.arg2.data_size);
297         EXPECT_EQ(0u, br.arg2.offsets_size);
298 
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 
311         bwr.write_buffer = (uintptr_t)&bc2;
312         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 
TEST_F(BinderDriverInterfaceTest,RequestDeathNotification)322 TEST_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 
357     bwr.write_buffer = (uintptr_t)&bc;
358     bwr.write_size = sizeof(bc);
359     bwr.read_buffer = (uintptr_t)&br;
360     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 
TEST_F(BinderDriverInterfaceTest,RequestFrozenNotification)371 TEST_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 
TEST_F(BinderDriverInterfaceTest,OverwritePendingFrozenNotification)455 TEST_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 
TEST_F(BinderDriverInterfaceTest,ResendFrozenNotification)517 TEST_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 
main(int argc,char ** argv)616 int main(int argc, char** argv) {
617     ::testing::InitGoogleTest(&argc, argv);
618 
619     binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
620 
621     return RUN_ALL_TESTS();
622 }
623