xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderDriverInterfaceTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <errno.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <fcntl.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <stdio.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker #include <binder/IBinder.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <linux/android/binder.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <poll.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <sys/ioctl.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <sys/mman.h>
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker #include "../binder_module.h"
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker #define BINDER_DEV_NAME "/dev/binder"
33*38e8c45fSAndroid Build Coastguard Worker 
34*38e8c45fSAndroid Build Coastguard Worker testing::Environment* binder_env;
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker class BinderDriverInterfaceTestEnv : public ::testing::Environment {
SetUp()37*38e8c45fSAndroid Build Coastguard Worker         virtual void SetUp() {
38*38e8c45fSAndroid Build Coastguard Worker             int ret;
39*38e8c45fSAndroid Build Coastguard Worker             uint32_t max_threads = 0;
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker             m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
42*38e8c45fSAndroid Build Coastguard Worker             ASSERT_GE(m_binderFd, 0);
43*38e8c45fSAndroid Build Coastguard Worker             m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
44*38e8c45fSAndroid Build Coastguard Worker             ASSERT_NE(m_buffer, (void *)nullptr);
45*38e8c45fSAndroid Build Coastguard Worker             ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
46*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(0, ret);
47*38e8c45fSAndroid Build Coastguard Worker             EnterLooper();
48*38e8c45fSAndroid Build Coastguard Worker         }
TearDown()49*38e8c45fSAndroid Build Coastguard Worker         virtual void TearDown() {
50*38e8c45fSAndroid Build Coastguard Worker             close(m_binderFd);
51*38e8c45fSAndroid Build Coastguard Worker         }
52*38e8c45fSAndroid Build Coastguard Worker     private:
53*38e8c45fSAndroid Build Coastguard Worker         int m_binderFd;
54*38e8c45fSAndroid Build Coastguard Worker         void *m_buffer;
55*38e8c45fSAndroid Build Coastguard Worker     public:
getBinderFd(void)56*38e8c45fSAndroid Build Coastguard Worker         int getBinderFd(void) {
57*38e8c45fSAndroid Build Coastguard Worker             return m_binderFd;
58*38e8c45fSAndroid Build Coastguard Worker         }
EnterLooper(void)59*38e8c45fSAndroid Build Coastguard Worker         void EnterLooper(void) {
60*38e8c45fSAndroid Build Coastguard Worker             int ret;
61*38e8c45fSAndroid Build Coastguard Worker             const uint32_t bc[] = {
62*38e8c45fSAndroid Build Coastguard Worker                 BC_ENTER_LOOPER,
63*38e8c45fSAndroid Build Coastguard Worker             };
64*38e8c45fSAndroid Build Coastguard Worker             struct binder_write_read bwr = binder_write_read();
65*38e8c45fSAndroid Build Coastguard Worker             bwr.write_buffer = (uintptr_t)bc;
66*38e8c45fSAndroid Build Coastguard Worker             bwr.write_size = sizeof(bc);
67*38e8c45fSAndroid Build Coastguard Worker             ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr);
68*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(0, ret);
69*38e8c45fSAndroid Build Coastguard Worker             if (ret < 0) {
70*38e8c45fSAndroid Build Coastguard Worker                     EXPECT_EQ(0, errno);
71*38e8c45fSAndroid Build Coastguard Worker             }
72*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(sizeof(bc), bwr.write_consumed);
73*38e8c45fSAndroid Build Coastguard Worker         }
74*38e8c45fSAndroid Build Coastguard Worker };
75*38e8c45fSAndroid Build Coastguard Worker 
76*38e8c45fSAndroid Build Coastguard Worker class BinderDriverInterfaceTest : public ::testing::Test {
77*38e8c45fSAndroid Build Coastguard Worker     public:
SetUp()78*38e8c45fSAndroid Build Coastguard Worker         virtual void SetUp() {
79*38e8c45fSAndroid Build Coastguard Worker             m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
80*38e8c45fSAndroid Build Coastguard Worker         }
TearDown()81*38e8c45fSAndroid Build Coastguard Worker         virtual void TearDown() {
82*38e8c45fSAndroid Build Coastguard Worker         }
83*38e8c45fSAndroid Build Coastguard Worker     protected:
84*38e8c45fSAndroid Build Coastguard Worker         /* 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*38e8c45fSAndroid Build Coastguard Worker         void binderTestIoctlSuccessOrError(int cmd, void *arg, int accepted_errno) {
86*38e8c45fSAndroid Build Coastguard Worker             int ret;
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker             ret = ioctl(m_binderFd, cmd, arg);
89*38e8c45fSAndroid Build Coastguard Worker             if (ret != 0) {
90*38e8c45fSAndroid Build Coastguard Worker                 EXPECT_EQ(errno, accepted_errno);
91*38e8c45fSAndroid Build Coastguard Worker             }
92*38e8c45fSAndroid Build Coastguard Worker         }
93*38e8c45fSAndroid Build Coastguard Worker 
binderTestIoctlRetErr2(int cmd,void * arg,int expect_ret,int expect_errno,int accept_errno)94*38e8c45fSAndroid Build Coastguard Worker         void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
95*38e8c45fSAndroid Build Coastguard Worker             int ret;
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker             ret = ioctl(m_binderFd, cmd, arg);
98*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(expect_ret, ret);
99*38e8c45fSAndroid Build Coastguard Worker             if (ret < 0) {
100*38e8c45fSAndroid Build Coastguard Worker                 if (errno != accept_errno) {
101*38e8c45fSAndroid Build Coastguard Worker                     EXPECT_EQ(expect_errno, errno);
102*38e8c45fSAndroid Build Coastguard Worker                 }
103*38e8c45fSAndroid Build Coastguard Worker             }
104*38e8c45fSAndroid Build Coastguard Worker         }
binderTestIoctlErr2(int cmd,void * arg,int expect_errno,int accept_errno)105*38e8c45fSAndroid Build Coastguard Worker         void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
106*38e8c45fSAndroid Build Coastguard Worker             binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
107*38e8c45fSAndroid Build Coastguard Worker         }
binderTestIoctlErr1(int cmd,void * arg,int expect_errno)108*38e8c45fSAndroid Build Coastguard Worker         void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
109*38e8c45fSAndroid Build Coastguard Worker             binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
110*38e8c45fSAndroid Build Coastguard Worker         }
binderTestIoctl(int cmd,void * arg)111*38e8c45fSAndroid Build Coastguard Worker         void binderTestIoctl(int cmd, void *arg) {
112*38e8c45fSAndroid Build Coastguard Worker             binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
113*38e8c45fSAndroid Build Coastguard Worker         }
binderTestIoctlUnimplemented(int cmd,void * arg)114*38e8c45fSAndroid Build Coastguard Worker         void binderTestIoctlUnimplemented(int cmd, void *arg) {
115*38e8c45fSAndroid Build Coastguard Worker             int ret;
116*38e8c45fSAndroid Build Coastguard Worker 
117*38e8c45fSAndroid Build Coastguard Worker             ret = ioctl(m_binderFd, cmd, arg);
118*38e8c45fSAndroid Build Coastguard Worker             if (ret < 0) {
119*38e8c45fSAndroid Build Coastguard Worker                 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
120*38e8c45fSAndroid Build Coastguard Worker                 EXPECT_EQ(-1, ret);
121*38e8c45fSAndroid Build Coastguard Worker                 EXPECT_EQ(EINVAL, errno);
122*38e8c45fSAndroid Build Coastguard Worker             }
123*38e8c45fSAndroid Build Coastguard Worker         }
binderTestReadEmpty(void)124*38e8c45fSAndroid Build Coastguard Worker         void binderTestReadEmpty(void) {
125*38e8c45fSAndroid Build Coastguard Worker             size_t i;
126*38e8c45fSAndroid Build Coastguard Worker             uint32_t br[32];
127*38e8c45fSAndroid Build Coastguard Worker             struct binder_write_read bwr = binder_write_read();
128*38e8c45fSAndroid Build Coastguard Worker             SCOPED_TRACE("TestReadEmpty");
129*38e8c45fSAndroid Build Coastguard Worker             bwr.read_buffer = (uintptr_t)br;
130*38e8c45fSAndroid Build Coastguard Worker             bwr.read_size = sizeof(br);
131*38e8c45fSAndroid Build Coastguard Worker             binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
132*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(0u, bwr.read_consumed);
133*38e8c45fSAndroid Build Coastguard Worker             for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
134*38e8c45fSAndroid Build Coastguard Worker                 SCOPED_TRACE(testing::Message() << "i = " << i);
135*38e8c45fSAndroid Build Coastguard Worker                 EXPECT_EQ(BR_NOOP, br[i]);
136*38e8c45fSAndroid Build Coastguard Worker             }
137*38e8c45fSAndroid Build Coastguard Worker         }
binderWaitForReadData(int timeout_ms)138*38e8c45fSAndroid Build Coastguard Worker         void binderWaitForReadData(int timeout_ms) {
139*38e8c45fSAndroid Build Coastguard Worker             int ret;
140*38e8c45fSAndroid Build Coastguard Worker             pollfd pfd = pollfd();
141*38e8c45fSAndroid Build Coastguard Worker 
142*38e8c45fSAndroid Build Coastguard Worker             pfd.fd = m_binderFd;
143*38e8c45fSAndroid Build Coastguard Worker             pfd.events = POLLIN;
144*38e8c45fSAndroid Build Coastguard Worker             ret = poll(&pfd, 1, timeout_ms);
145*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(1, ret);
146*38e8c45fSAndroid Build Coastguard Worker         }
147*38e8c45fSAndroid Build Coastguard Worker     private:
148*38e8c45fSAndroid Build Coastguard Worker         int m_binderFd;
149*38e8c45fSAndroid Build Coastguard Worker };
150*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,Version)151*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, Version) {
152*38e8c45fSAndroid Build Coastguard Worker     struct binder_version version;
153*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_VERSION, &version);
154*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
155*38e8c45fSAndroid Build Coastguard Worker }
156*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,OpenNoMmap)157*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, OpenNoMmap) {
158*38e8c45fSAndroid Build Coastguard Worker     int binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
159*38e8c45fSAndroid Build Coastguard Worker     ASSERT_GE(binderFd, 0);
160*38e8c45fSAndroid Build Coastguard Worker     close(binderFd);
161*38e8c45fSAndroid Build Coastguard Worker }
162*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,WriteReadNull)163*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
164*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
165*38e8c45fSAndroid Build Coastguard Worker }
166*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNull)167*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
168*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,SetMaxThreadsNull)171*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
172*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
173*38e8c45fSAndroid Build Coastguard Worker }
174*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNull)175*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
176*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
177*38e8c45fSAndroid Build Coastguard Worker }
178*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,VersionNull)179*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, VersionNull) {
180*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
181*38e8c45fSAndroid Build Coastguard Worker }
182*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNoTest)183*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
184*38e8c45fSAndroid Build Coastguard Worker     int64_t idle_timeout = 100000;
185*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
186*38e8c45fSAndroid Build Coastguard Worker }
187*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,SetMaxThreads)188*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
189*38e8c45fSAndroid Build Coastguard Worker     uint32_t max_threads = 0;
190*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
191*38e8c45fSAndroid Build Coastguard Worker }
192*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNoTest)193*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
194*38e8c45fSAndroid Build Coastguard Worker     int idle_priority = 0;
195*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
196*38e8c45fSAndroid Build Coastguard Worker }
197*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,SetContextMgrBusy)198*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
199*38e8c45fSAndroid Build Coastguard Worker     int32_t dummy = 0;
200*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
201*38e8c45fSAndroid Build Coastguard Worker }
202*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,ThreadExit)203*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, ThreadExit) {
204*38e8c45fSAndroid Build Coastguard Worker     int32_t dummy = 0;
205*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
206*38e8c45fSAndroid Build Coastguard Worker     static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
207*38e8c45fSAndroid Build Coastguard Worker }
208*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,WriteReadEmpty)209*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
210*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr = binder_write_read();
211*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr);
212*38e8c45fSAndroid Build Coastguard Worker }
213*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,Read)214*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, Read) {
215*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
216*38e8c45fSAndroid Build Coastguard Worker }
217*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,IncRefsAcquireReleaseDecRefs)218*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
219*38e8c45fSAndroid Build Coastguard Worker     const uint32_t bc[] = {
220*38e8c45fSAndroid Build Coastguard Worker         BC_INCREFS,
221*38e8c45fSAndroid Build Coastguard Worker         0,
222*38e8c45fSAndroid Build Coastguard Worker         BC_ACQUIRE,
223*38e8c45fSAndroid Build Coastguard Worker         0,
224*38e8c45fSAndroid Build Coastguard Worker         BC_RELEASE,
225*38e8c45fSAndroid Build Coastguard Worker         0,
226*38e8c45fSAndroid Build Coastguard Worker         BC_DECREFS,
227*38e8c45fSAndroid Build Coastguard Worker         0,
228*38e8c45fSAndroid Build Coastguard Worker     };
229*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr = binder_write_read();
230*38e8c45fSAndroid Build Coastguard Worker     bwr.write_buffer = (uintptr_t)bc;
231*38e8c45fSAndroid Build Coastguard Worker     bwr.write_size = sizeof(bc);
232*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr);
233*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc), bwr.write_consumed);
234*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
235*38e8c45fSAndroid Build Coastguard Worker }
236*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,Transaction)237*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, Transaction) {
238*38e8c45fSAndroid Build Coastguard Worker     struct {
239*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
240*38e8c45fSAndroid Build Coastguard Worker         struct binder_transaction_data arg1;
241*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc1 = {
242*38e8c45fSAndroid Build Coastguard Worker         .cmd1 = BC_TRANSACTION,
243*38e8c45fSAndroid Build Coastguard Worker         .arg1 = {
244*38e8c45fSAndroid Build Coastguard Worker             .target = { 0 },
245*38e8c45fSAndroid Build Coastguard Worker             .cookie = 0,
246*38e8c45fSAndroid Build Coastguard Worker             .code = android::IBinder::PING_TRANSACTION,
247*38e8c45fSAndroid Build Coastguard Worker             .flags = 0,
248*38e8c45fSAndroid Build Coastguard Worker             .sender_pid = 0,
249*38e8c45fSAndroid Build Coastguard Worker             .sender_euid = 0,
250*38e8c45fSAndroid Build Coastguard Worker             .data_size = 0,
251*38e8c45fSAndroid Build Coastguard Worker             .offsets_size = 0,
252*38e8c45fSAndroid Build Coastguard Worker             .data = {
253*38e8c45fSAndroid Build Coastguard Worker                 .ptr = {0, 0},
254*38e8c45fSAndroid Build Coastguard Worker             },
255*38e8c45fSAndroid Build Coastguard Worker         },
256*38e8c45fSAndroid Build Coastguard Worker     };
257*38e8c45fSAndroid Build Coastguard Worker     struct {
258*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
259*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
260*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd2;
261*38e8c45fSAndroid Build Coastguard Worker         binder_transaction_data arg2;
262*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
263*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br;
264*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr = binder_write_read();
265*38e8c45fSAndroid Build Coastguard Worker 
266*38e8c45fSAndroid Build Coastguard Worker     bwr.write_buffer = (uintptr_t)&bc1;
267*38e8c45fSAndroid Build Coastguard Worker     bwr.write_size = sizeof(bc1);
268*38e8c45fSAndroid Build Coastguard Worker     bwr.read_buffer = (uintptr_t)&br;
269*38e8c45fSAndroid Build Coastguard Worker     bwr.read_size = sizeof(br);
270*38e8c45fSAndroid Build Coastguard Worker 
271*38e8c45fSAndroid Build Coastguard Worker     {
272*38e8c45fSAndroid Build Coastguard Worker         SCOPED_TRACE("1st WriteRead");
273*38e8c45fSAndroid Build Coastguard Worker         binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
274*38e8c45fSAndroid Build Coastguard Worker     }
275*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
276*38e8c45fSAndroid Build Coastguard Worker     if (bwr.read_consumed < offsetof(typeof(br), pad)) {
277*38e8c45fSAndroid Build Coastguard Worker         SCOPED_TRACE("2nd WriteRead");
278*38e8c45fSAndroid Build Coastguard Worker         binderWaitForReadData(10000);
279*38e8c45fSAndroid Build Coastguard Worker         binderTestIoctl(BINDER_WRITE_READ, &bwr);
280*38e8c45fSAndroid Build Coastguard Worker     }
281*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
282*38e8c45fSAndroid Build Coastguard Worker     if (bwr.read_consumed > offsetof(typeof(br), cmd0)) {
283*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(BR_NOOP, br.cmd0);
284*38e8c45fSAndroid Build Coastguard Worker     }
285*38e8c45fSAndroid Build Coastguard Worker     if (bwr.read_consumed > offsetof(typeof(br), cmd1)) {
286*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
287*38e8c45fSAndroid Build Coastguard Worker     }
288*38e8c45fSAndroid Build Coastguard Worker     if (bwr.read_consumed > offsetof(typeof(br), cmd2)) {
289*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(BR_REPLY, br.cmd2);
290*38e8c45fSAndroid Build Coastguard Worker     }
291*38e8c45fSAndroid Build Coastguard Worker     if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
292*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0u, br.arg2.target.ptr);
293*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0u, br.arg2.cookie);
294*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0u, br.arg2.code);
295*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0u, br.arg2.flags);
296*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0u, br.arg2.data_size);
297*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0u, br.arg2.offsets_size);
298*38e8c45fSAndroid Build Coastguard Worker 
299*38e8c45fSAndroid Build Coastguard Worker         SCOPED_TRACE("3rd WriteRead");
300*38e8c45fSAndroid Build Coastguard Worker 
301*38e8c45fSAndroid Build Coastguard Worker         binderTestReadEmpty();
302*38e8c45fSAndroid Build Coastguard Worker 
303*38e8c45fSAndroid Build Coastguard Worker         struct {
304*38e8c45fSAndroid Build Coastguard Worker             uint32_t cmd1;
305*38e8c45fSAndroid Build Coastguard Worker             binder_uintptr_t arg1;
306*38e8c45fSAndroid Build Coastguard Worker         } __attribute__((packed)) bc2 = {
307*38e8c45fSAndroid Build Coastguard Worker             .cmd1 = BC_FREE_BUFFER,
308*38e8c45fSAndroid Build Coastguard Worker             .arg1 = br.arg2.data.ptr.buffer,
309*38e8c45fSAndroid Build Coastguard Worker         };
310*38e8c45fSAndroid Build Coastguard Worker 
311*38e8c45fSAndroid Build Coastguard Worker         bwr.write_buffer = (uintptr_t)&bc2;
312*38e8c45fSAndroid Build Coastguard Worker         bwr.write_size = sizeof(bc2);
313*38e8c45fSAndroid Build Coastguard Worker         bwr.write_consumed = 0;
314*38e8c45fSAndroid Build Coastguard Worker         bwr.read_size = 0;
315*38e8c45fSAndroid Build Coastguard Worker 
316*38e8c45fSAndroid Build Coastguard Worker         binderTestIoctl(BINDER_WRITE_READ, &bwr);
317*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
318*38e8c45fSAndroid Build Coastguard Worker     }
319*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
320*38e8c45fSAndroid Build Coastguard Worker }
321*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,RequestDeathNotification)322*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
323*38e8c45fSAndroid Build Coastguard Worker     binder_uintptr_t cookie = 1234;
324*38e8c45fSAndroid Build Coastguard Worker     struct {
325*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
326*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg0;
327*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
328*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg1;
329*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd2;
330*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg2;
331*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd3;
332*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg3;
333*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc = {
334*38e8c45fSAndroid Build Coastguard Worker         .cmd0 = BC_INCREFS,
335*38e8c45fSAndroid Build Coastguard Worker         .arg0 = 0,
336*38e8c45fSAndroid Build Coastguard Worker         .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
337*38e8c45fSAndroid Build Coastguard Worker         .arg1 = {
338*38e8c45fSAndroid Build Coastguard Worker             .handle = 0,
339*38e8c45fSAndroid Build Coastguard Worker             .cookie = cookie,
340*38e8c45fSAndroid Build Coastguard Worker         },
341*38e8c45fSAndroid Build Coastguard Worker         .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
342*38e8c45fSAndroid Build Coastguard Worker         .arg2 = {
343*38e8c45fSAndroid Build Coastguard Worker             .handle = 0,
344*38e8c45fSAndroid Build Coastguard Worker             .cookie = cookie,
345*38e8c45fSAndroid Build Coastguard Worker         },
346*38e8c45fSAndroid Build Coastguard Worker         .cmd3 = BC_DECREFS,
347*38e8c45fSAndroid Build Coastguard Worker         .arg3 = 0,
348*38e8c45fSAndroid Build Coastguard Worker     };
349*38e8c45fSAndroid Build Coastguard Worker     struct {
350*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
351*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
352*38e8c45fSAndroid Build Coastguard Worker         binder_uintptr_t arg1;
353*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
354*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br;
355*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr = binder_write_read();
356*38e8c45fSAndroid Build Coastguard Worker 
357*38e8c45fSAndroid Build Coastguard Worker     bwr.write_buffer = (uintptr_t)&bc;
358*38e8c45fSAndroid Build Coastguard Worker     bwr.write_size = sizeof(bc);
359*38e8c45fSAndroid Build Coastguard Worker     bwr.read_buffer = (uintptr_t)&br;
360*38e8c45fSAndroid Build Coastguard Worker     bwr.read_size = sizeof(br);
361*38e8c45fSAndroid Build Coastguard Worker 
362*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr);
363*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc), bwr.write_consumed);
364*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
365*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_NOOP, br.cmd0);
366*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
367*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(cookie, br.arg1);
368*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
369*38e8c45fSAndroid Build Coastguard Worker }
370*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,RequestFrozenNotification)371*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, RequestFrozenNotification) {
372*38e8c45fSAndroid Build Coastguard Worker     if (!android::ProcessState::isDriverFeatureEnabled(
373*38e8c45fSAndroid Build Coastguard Worker                 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
374*38e8c45fSAndroid Build Coastguard Worker         GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
375*38e8c45fSAndroid Build Coastguard Worker         return;
376*38e8c45fSAndroid Build Coastguard Worker     }
377*38e8c45fSAndroid Build Coastguard Worker     binder_uintptr_t cookie = 1234;
378*38e8c45fSAndroid Build Coastguard Worker     struct {
379*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
380*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg0;
381*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
382*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg1;
383*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc1 = {
384*38e8c45fSAndroid Build Coastguard Worker             .cmd0 = BC_INCREFS,
385*38e8c45fSAndroid Build Coastguard Worker             .arg0 = 0,
386*38e8c45fSAndroid Build Coastguard Worker             .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
387*38e8c45fSAndroid Build Coastguard Worker             .arg1 =
388*38e8c45fSAndroid Build Coastguard Worker                     {
389*38e8c45fSAndroid Build Coastguard Worker                             .handle = 0,
390*38e8c45fSAndroid Build Coastguard Worker                             .cookie = cookie,
391*38e8c45fSAndroid Build Coastguard Worker                     },
392*38e8c45fSAndroid Build Coastguard Worker     };
393*38e8c45fSAndroid Build Coastguard Worker     struct {
394*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
395*38e8c45fSAndroid Build Coastguard Worker         // Expecting a BR_FROZEN_BINDER since BC_REQUEST_FREEZE_NOTIFICATION
396*38e8c45fSAndroid Build Coastguard Worker         // above should lead to an immediate notification of the current state.
397*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
398*38e8c45fSAndroid Build Coastguard Worker         struct binder_frozen_state_info arg1;
399*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
400*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br1;
401*38e8c45fSAndroid Build Coastguard Worker     struct {
402*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd2;
403*38e8c45fSAndroid Build Coastguard Worker         binder_uintptr_t arg2;
404*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd3;
405*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg3;
406*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd4;
407*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg4;
408*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc2 = {
409*38e8c45fSAndroid Build Coastguard Worker             // Tell kernel that userspace has done handling BR_FROZEN_BINDER.
410*38e8c45fSAndroid Build Coastguard Worker             .cmd2 = BC_FREEZE_NOTIFICATION_DONE,
411*38e8c45fSAndroid Build Coastguard Worker             .arg2 = cookie,
412*38e8c45fSAndroid Build Coastguard Worker             .cmd3 = BC_CLEAR_FREEZE_NOTIFICATION,
413*38e8c45fSAndroid Build Coastguard Worker             .arg3 =
414*38e8c45fSAndroid Build Coastguard Worker                     {
415*38e8c45fSAndroid Build Coastguard Worker                             .handle = 0,
416*38e8c45fSAndroid Build Coastguard Worker                             .cookie = cookie,
417*38e8c45fSAndroid Build Coastguard Worker                     },
418*38e8c45fSAndroid Build Coastguard Worker             .cmd4 = BC_DECREFS,
419*38e8c45fSAndroid Build Coastguard Worker             .arg4 = 0,
420*38e8c45fSAndroid Build Coastguard Worker     };
421*38e8c45fSAndroid Build Coastguard Worker     struct {
422*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd2;
423*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd3;
424*38e8c45fSAndroid Build Coastguard Worker         binder_uintptr_t arg3;
425*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
426*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br2;
427*38e8c45fSAndroid Build Coastguard Worker 
428*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr1 = binder_write_read();
429*38e8c45fSAndroid Build Coastguard Worker     bwr1.write_buffer = (uintptr_t)&bc1;
430*38e8c45fSAndroid Build Coastguard Worker     bwr1.write_size = sizeof(bc1);
431*38e8c45fSAndroid Build Coastguard Worker     bwr1.read_buffer = (uintptr_t)&br1;
432*38e8c45fSAndroid Build Coastguard Worker     bwr1.read_size = sizeof(br1);
433*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr1);
434*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc1), bwr1.write_consumed);
435*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(br1) - sizeof(br1.pad), bwr1.read_consumed);
436*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_NOOP, br1.cmd0);
437*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(BR_FROZEN_BINDER, br1.cmd1);
438*38e8c45fSAndroid Build Coastguard Worker     EXPECT_FALSE(br1.arg1.is_frozen);
439*38e8c45fSAndroid Build Coastguard Worker 
440*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr2 = binder_write_read();
441*38e8c45fSAndroid Build Coastguard Worker     bwr2.write_buffer = (uintptr_t)&bc2;
442*38e8c45fSAndroid Build Coastguard Worker     bwr2.write_size = sizeof(bc2);
443*38e8c45fSAndroid Build Coastguard Worker     bwr2.read_buffer = (uintptr_t)&br2;
444*38e8c45fSAndroid Build Coastguard Worker     bwr2.read_size = sizeof(br2);
445*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr2);
446*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc2), bwr2.write_consumed);
447*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(br2) - sizeof(br2.pad), bwr2.read_consumed);
448*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_NOOP, br2.cmd2);
449*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br2.cmd3);
450*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(cookie, br2.arg3);
451*38e8c45fSAndroid Build Coastguard Worker 
452*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
453*38e8c45fSAndroid Build Coastguard Worker }
454*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,OverwritePendingFrozenNotification)455*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, OverwritePendingFrozenNotification) {
456*38e8c45fSAndroid Build Coastguard Worker     if (!android::ProcessState::isDriverFeatureEnabled(
457*38e8c45fSAndroid Build Coastguard Worker                 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
458*38e8c45fSAndroid Build Coastguard Worker         GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
459*38e8c45fSAndroid Build Coastguard Worker         return;
460*38e8c45fSAndroid Build Coastguard Worker     }
461*38e8c45fSAndroid Build Coastguard Worker     binder_uintptr_t cookie = 1234;
462*38e8c45fSAndroid Build Coastguard Worker     struct {
463*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
464*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg0;
465*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
466*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg1;
467*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd2;
468*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg2;
469*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd3;
470*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg3;
471*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc = {
472*38e8c45fSAndroid Build Coastguard Worker             .cmd0 = BC_INCREFS,
473*38e8c45fSAndroid Build Coastguard Worker             .arg0 = 0,
474*38e8c45fSAndroid Build Coastguard Worker             .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
475*38e8c45fSAndroid Build Coastguard Worker             // This BC_REQUEST_FREEZE_NOTIFICATION should lead to a pending
476*38e8c45fSAndroid Build Coastguard Worker             // frozen notification inserted into the queue.
477*38e8c45fSAndroid Build Coastguard Worker             .arg1 =
478*38e8c45fSAndroid Build Coastguard Worker                     {
479*38e8c45fSAndroid Build Coastguard Worker                             .handle = 0,
480*38e8c45fSAndroid Build Coastguard Worker                             .cookie = cookie,
481*38e8c45fSAndroid Build Coastguard Worker                     },
482*38e8c45fSAndroid Build Coastguard Worker             // Send BC_CLEAR_FREEZE_NOTIFICATION before the above frozen
483*38e8c45fSAndroid Build Coastguard Worker             // notification has a chance of being sent. The notification should
484*38e8c45fSAndroid Build Coastguard Worker             // be overwritten. Userspace is expected to only receive
485*38e8c45fSAndroid Build Coastguard Worker             // BR_CLEAR_FREEZE_NOTIFICATION_DONE.
486*38e8c45fSAndroid Build Coastguard Worker             .cmd2 = BC_CLEAR_FREEZE_NOTIFICATION,
487*38e8c45fSAndroid Build Coastguard Worker             .arg2 =
488*38e8c45fSAndroid Build Coastguard Worker                     {
489*38e8c45fSAndroid Build Coastguard Worker                             .handle = 0,
490*38e8c45fSAndroid Build Coastguard Worker                             .cookie = cookie,
491*38e8c45fSAndroid Build Coastguard Worker                     },
492*38e8c45fSAndroid Build Coastguard Worker             .cmd3 = BC_DECREFS,
493*38e8c45fSAndroid Build Coastguard Worker             .arg3 = 0,
494*38e8c45fSAndroid Build Coastguard Worker     };
495*38e8c45fSAndroid Build Coastguard Worker     struct {
496*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
497*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
498*38e8c45fSAndroid Build Coastguard Worker         binder_uintptr_t arg1;
499*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
500*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br;
501*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr = binder_write_read();
502*38e8c45fSAndroid Build Coastguard Worker 
503*38e8c45fSAndroid Build Coastguard Worker     bwr.write_buffer = (uintptr_t)&bc;
504*38e8c45fSAndroid Build Coastguard Worker     bwr.write_size = sizeof(bc);
505*38e8c45fSAndroid Build Coastguard Worker     bwr.read_buffer = (uintptr_t)&br;
506*38e8c45fSAndroid Build Coastguard Worker     bwr.read_size = sizeof(br);
507*38e8c45fSAndroid Build Coastguard Worker 
508*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr);
509*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc), bwr.write_consumed);
510*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
511*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_NOOP, br.cmd0);
512*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br.cmd1);
513*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(cookie, br.arg1);
514*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
515*38e8c45fSAndroid Build Coastguard Worker }
516*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(BinderDriverInterfaceTest,ResendFrozenNotification)517*38e8c45fSAndroid Build Coastguard Worker TEST_F(BinderDriverInterfaceTest, ResendFrozenNotification) {
518*38e8c45fSAndroid Build Coastguard Worker     if (!android::ProcessState::isDriverFeatureEnabled(
519*38e8c45fSAndroid Build Coastguard Worker                 android::ProcessState::DriverFeature::FREEZE_NOTIFICATION)) {
520*38e8c45fSAndroid Build Coastguard Worker         GTEST_SKIP() << "Skipping test for kernels that support freeze notification";
521*38e8c45fSAndroid Build Coastguard Worker         return;
522*38e8c45fSAndroid Build Coastguard Worker     }
523*38e8c45fSAndroid Build Coastguard Worker     binder_uintptr_t cookie = 1234;
524*38e8c45fSAndroid Build Coastguard Worker     struct {
525*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
526*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg0;
527*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
528*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg1;
529*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc1 = {
530*38e8c45fSAndroid Build Coastguard Worker             .cmd0 = BC_INCREFS,
531*38e8c45fSAndroid Build Coastguard Worker             .arg0 = 0,
532*38e8c45fSAndroid Build Coastguard Worker             .cmd1 = BC_REQUEST_FREEZE_NOTIFICATION,
533*38e8c45fSAndroid Build Coastguard Worker             .arg1 =
534*38e8c45fSAndroid Build Coastguard Worker                     {
535*38e8c45fSAndroid Build Coastguard Worker                             .handle = 0,
536*38e8c45fSAndroid Build Coastguard Worker                             .cookie = cookie,
537*38e8c45fSAndroid Build Coastguard Worker                     },
538*38e8c45fSAndroid Build Coastguard Worker     };
539*38e8c45fSAndroid Build Coastguard Worker     struct {
540*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd0;
541*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd1;
542*38e8c45fSAndroid Build Coastguard Worker         struct binder_frozen_state_info arg1;
543*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
544*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br1;
545*38e8c45fSAndroid Build Coastguard Worker     struct {
546*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd2;
547*38e8c45fSAndroid Build Coastguard Worker         struct binder_handle_cookie arg2;
548*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc2 = {
549*38e8c45fSAndroid Build Coastguard Worker             // Clear the notification before acknowledging the in-flight
550*38e8c45fSAndroid Build Coastguard Worker             // BR_FROZEN_BINDER. Kernel should hold off sending
551*38e8c45fSAndroid Build Coastguard Worker             // BR_CLEAR_FREEZE_NOTIFICATION_DONE until the acknowledgement
552*38e8c45fSAndroid Build Coastguard Worker             // reaches kernel.
553*38e8c45fSAndroid Build Coastguard Worker             .cmd2 = BC_CLEAR_FREEZE_NOTIFICATION,
554*38e8c45fSAndroid Build Coastguard Worker             .arg2 =
555*38e8c45fSAndroid Build Coastguard Worker                     {
556*38e8c45fSAndroid Build Coastguard Worker                             .handle = 0,
557*38e8c45fSAndroid Build Coastguard Worker                             .cookie = cookie,
558*38e8c45fSAndroid Build Coastguard Worker                     },
559*38e8c45fSAndroid Build Coastguard Worker     };
560*38e8c45fSAndroid Build Coastguard Worker     struct {
561*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
562*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br2;
563*38e8c45fSAndroid Build Coastguard Worker     struct {
564*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd3;
565*38e8c45fSAndroid Build Coastguard Worker         binder_uintptr_t arg3;
566*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd4;
567*38e8c45fSAndroid Build Coastguard Worker         uint32_t arg4;
568*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) bc3 = {
569*38e8c45fSAndroid Build Coastguard Worker             // Send the acknowledgement. Now the kernel should send out
570*38e8c45fSAndroid Build Coastguard Worker             // BR_CLEAR_FREEZE_NOTIFICATION_DONE.
571*38e8c45fSAndroid Build Coastguard Worker             .cmd3 = BC_FREEZE_NOTIFICATION_DONE,
572*38e8c45fSAndroid Build Coastguard Worker             .arg3 = cookie,
573*38e8c45fSAndroid Build Coastguard Worker             .cmd4 = BC_DECREFS,
574*38e8c45fSAndroid Build Coastguard Worker             .arg4 = 0,
575*38e8c45fSAndroid Build Coastguard Worker     };
576*38e8c45fSAndroid Build Coastguard Worker     struct {
577*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd2;
578*38e8c45fSAndroid Build Coastguard Worker         uint32_t cmd3;
579*38e8c45fSAndroid Build Coastguard Worker         binder_uintptr_t arg3;
580*38e8c45fSAndroid Build Coastguard Worker         uint32_t pad[16];
581*38e8c45fSAndroid Build Coastguard Worker     } __attribute__((packed)) br3;
582*38e8c45fSAndroid Build Coastguard Worker 
583*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr1 = binder_write_read();
584*38e8c45fSAndroid Build Coastguard Worker     bwr1.write_buffer = (uintptr_t)&bc1;
585*38e8c45fSAndroid Build Coastguard Worker     bwr1.write_size = sizeof(bc1);
586*38e8c45fSAndroid Build Coastguard Worker     bwr1.read_buffer = (uintptr_t)&br1;
587*38e8c45fSAndroid Build Coastguard Worker     bwr1.read_size = sizeof(br1);
588*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr1);
589*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc1), bwr1.write_consumed);
590*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(br1) - sizeof(br1.pad), bwr1.read_consumed);
591*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_NOOP, br1.cmd0);
592*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(BR_FROZEN_BINDER, br1.cmd1);
593*38e8c45fSAndroid Build Coastguard Worker     EXPECT_FALSE(br1.arg1.is_frozen);
594*38e8c45fSAndroid Build Coastguard Worker 
595*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr2 = binder_write_read();
596*38e8c45fSAndroid Build Coastguard Worker     bwr2.write_buffer = (uintptr_t)&bc2;
597*38e8c45fSAndroid Build Coastguard Worker     bwr2.write_size = sizeof(bc2);
598*38e8c45fSAndroid Build Coastguard Worker     bwr2.read_buffer = (uintptr_t)&br2;
599*38e8c45fSAndroid Build Coastguard Worker     bwr2.read_size = sizeof(br2);
600*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr2, EAGAIN);
601*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
602*38e8c45fSAndroid Build Coastguard Worker 
603*38e8c45fSAndroid Build Coastguard Worker     struct binder_write_read bwr3 = binder_write_read();
604*38e8c45fSAndroid Build Coastguard Worker     bwr3.write_buffer = (uintptr_t)&bc3;
605*38e8c45fSAndroid Build Coastguard Worker     bwr3.write_size = sizeof(bc3);
606*38e8c45fSAndroid Build Coastguard Worker     bwr3.read_buffer = (uintptr_t)&br3;
607*38e8c45fSAndroid Build Coastguard Worker     bwr3.read_size = sizeof(br3);
608*38e8c45fSAndroid Build Coastguard Worker     binderTestIoctl(BINDER_WRITE_READ, &bwr3);
609*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(bc3), bwr3.write_consumed);
610*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(sizeof(br3) - sizeof(br3.pad), bwr3.read_consumed);
611*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(BR_CLEAR_FREEZE_NOTIFICATION_DONE, br3.cmd3);
612*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(cookie, br3.arg3);
613*38e8c45fSAndroid Build Coastguard Worker     binderTestReadEmpty();
614*38e8c45fSAndroid Build Coastguard Worker }
615*38e8c45fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)616*38e8c45fSAndroid Build Coastguard Worker int main(int argc, char** argv) {
617*38e8c45fSAndroid Build Coastguard Worker     ::testing::InitGoogleTest(&argc, argv);
618*38e8c45fSAndroid Build Coastguard Worker 
619*38e8c45fSAndroid Build Coastguard Worker     binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
620*38e8c45fSAndroid Build Coastguard Worker 
621*38e8c45fSAndroid Build Coastguard Worker     return RUN_ALL_TESTS();
622*38e8c45fSAndroid Build Coastguard Worker }
623