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