xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderParcelUnitTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2020 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 <binder/IPCThreadState.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <binder/Status.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <cutils/ashmem.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker using android::BBinder;
24*38e8c45fSAndroid Build Coastguard Worker using android::IBinder;
25*38e8c45fSAndroid Build Coastguard Worker using android::IPCThreadState;
26*38e8c45fSAndroid Build Coastguard Worker using android::NO_ERROR;
27*38e8c45fSAndroid Build Coastguard Worker using android::OK;
28*38e8c45fSAndroid Build Coastguard Worker using android::Parcel;
29*38e8c45fSAndroid Build Coastguard Worker using android::sp;
30*38e8c45fSAndroid Build Coastguard Worker using android::status_t;
31*38e8c45fSAndroid Build Coastguard Worker using android::String16;
32*38e8c45fSAndroid Build Coastguard Worker using android::String8;
33*38e8c45fSAndroid Build Coastguard Worker using android::binder::Status;
34*38e8c45fSAndroid Build Coastguard Worker using android::binder::unique_fd;
35*38e8c45fSAndroid Build Coastguard Worker 
checkCString(const char * str)36*38e8c45fSAndroid Build Coastguard Worker static void checkCString(const char* str) {
37*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < 3; i++) {
38*38e8c45fSAndroid Build Coastguard Worker         Parcel p;
39*38e8c45fSAndroid Build Coastguard Worker 
40*38e8c45fSAndroid Build Coastguard Worker         for (size_t j = 0; j < i; j++) p.writeInt32(3);
41*38e8c45fSAndroid Build Coastguard Worker 
42*38e8c45fSAndroid Build Coastguard Worker         p.writeCString(str);
43*38e8c45fSAndroid Build Coastguard Worker         int32_t pos = p.dataPosition();
44*38e8c45fSAndroid Build Coastguard Worker 
45*38e8c45fSAndroid Build Coastguard Worker         p.setDataPosition(0);
46*38e8c45fSAndroid Build Coastguard Worker 
47*38e8c45fSAndroid Build Coastguard Worker         for (size_t j = 0; j < i; j++) p.readInt32();
48*38e8c45fSAndroid Build Coastguard Worker         const char* str2 = p.readCString();
49*38e8c45fSAndroid Build Coastguard Worker 
50*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(std::string(str), str2);
51*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(pos, p.dataPosition());
52*38e8c45fSAndroid Build Coastguard Worker     }
53*38e8c45fSAndroid Build Coastguard Worker }
54*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,TestReadCString)55*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, TestReadCString) {
56*38e8c45fSAndroid Build Coastguard Worker     // we should remove the *CString APIs, but testing them until
57*38e8c45fSAndroid Build Coastguard Worker     // they are deleted.
58*38e8c45fSAndroid Build Coastguard Worker     checkCString("");
59*38e8c45fSAndroid Build Coastguard Worker     checkCString("a");
60*38e8c45fSAndroid Build Coastguard Worker     checkCString("\n");
61*38e8c45fSAndroid Build Coastguard Worker     checkCString("32");
62*38e8c45fSAndroid Build Coastguard Worker     checkCString("321");
63*38e8c45fSAndroid Build Coastguard Worker     checkCString("3210");
64*38e8c45fSAndroid Build Coastguard Worker     checkCString("3210b");
65*38e8c45fSAndroid Build Coastguard Worker     checkCString("123434");
66*38e8c45fSAndroid Build Coastguard Worker }
67*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,NonNullTerminatedString8)68*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, NonNullTerminatedString8) {
69*38e8c45fSAndroid Build Coastguard Worker     String8 kTestString = String8("test-is-good");
70*38e8c45fSAndroid Build Coastguard Worker 
71*38e8c45fSAndroid Build Coastguard Worker     // write non-null terminated string
72*38e8c45fSAndroid Build Coastguard Worker     Parcel p;
73*38e8c45fSAndroid Build Coastguard Worker     p.writeString8(kTestString);
74*38e8c45fSAndroid Build Coastguard Worker     p.setDataPosition(0);
75*38e8c45fSAndroid Build Coastguard Worker     // BAD! assumption of wire format for test
76*38e8c45fSAndroid Build Coastguard Worker     // write over length of string
77*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(kTestString.size() - 2);
78*38e8c45fSAndroid Build Coastguard Worker 
79*38e8c45fSAndroid Build Coastguard Worker     p.setDataPosition(0);
80*38e8c45fSAndroid Build Coastguard Worker     String8 output;
81*38e8c45fSAndroid Build Coastguard Worker     EXPECT_NE(OK, p.readString8(&output));
82*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(output.size(), 0);
83*38e8c45fSAndroid Build Coastguard Worker }
84*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,NonNullTerminatedString16)85*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, NonNullTerminatedString16) {
86*38e8c45fSAndroid Build Coastguard Worker     String16 kTestString = String16("test-is-good");
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker     // write non-null terminated string
89*38e8c45fSAndroid Build Coastguard Worker     Parcel p;
90*38e8c45fSAndroid Build Coastguard Worker     p.writeString16(kTestString);
91*38e8c45fSAndroid Build Coastguard Worker     p.setDataPosition(0);
92*38e8c45fSAndroid Build Coastguard Worker     // BAD! assumption of wire format for test
93*38e8c45fSAndroid Build Coastguard Worker     // write over length of string
94*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(kTestString.size() - 2);
95*38e8c45fSAndroid Build Coastguard Worker 
96*38e8c45fSAndroid Build Coastguard Worker     p.setDataPosition(0);
97*38e8c45fSAndroid Build Coastguard Worker     String16 output;
98*38e8c45fSAndroid Build Coastguard Worker     EXPECT_NE(OK, p.readString16(&output));
99*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(output.size(), 0);
100*38e8c45fSAndroid Build Coastguard Worker }
101*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,EnforceNoDataAvail)102*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, EnforceNoDataAvail) {
103*38e8c45fSAndroid Build Coastguard Worker     const int32_t kTestInt = 42;
104*38e8c45fSAndroid Build Coastguard Worker     const String8 kTestString = String8("test-is-good");
105*38e8c45fSAndroid Build Coastguard Worker     Parcel p;
106*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(kTestInt);
107*38e8c45fSAndroid Build Coastguard Worker     p.writeString8(kTestString);
108*38e8c45fSAndroid Build Coastguard Worker     p.setDataPosition(0);
109*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(kTestInt, p.readInt32());
110*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_BAD_PARCELABLE);
111*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(kTestString, p.readString8());
112*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_NONE);
113*38e8c45fSAndroid Build Coastguard Worker }
114*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,DebugReadAllBinders)115*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, DebugReadAllBinders) {
116*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder1 = sp<BBinder>::make();
117*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder2 = sp<BBinder>::make();
118*38e8c45fSAndroid Build Coastguard Worker 
119*38e8c45fSAndroid Build Coastguard Worker     Parcel p;
120*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(4);
121*38e8c45fSAndroid Build Coastguard Worker     p.writeStrongBinder(binder1);
122*38e8c45fSAndroid Build Coastguard Worker     p.writeStrongBinder(nullptr);
123*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(4);
124*38e8c45fSAndroid Build Coastguard Worker     p.writeStrongBinder(binder2);
125*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(4);
126*38e8c45fSAndroid Build Coastguard Worker 
127*38e8c45fSAndroid Build Coastguard Worker     auto ret = p.debugReadAllStrongBinders();
128*38e8c45fSAndroid Build Coastguard Worker 
129*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(ret.size(), 2);
130*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(ret[0], binder1);
131*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(ret[1], binder2);
132*38e8c45fSAndroid Build Coastguard Worker }
133*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,DebugReadAllFds)134*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, DebugReadAllFds) {
135*38e8c45fSAndroid Build Coastguard Worker     Parcel p;
136*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(4);
137*38e8c45fSAndroid Build Coastguard Worker     p.writeFileDescriptor(STDOUT_FILENO, false /*takeOwnership*/);
138*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(4);
139*38e8c45fSAndroid Build Coastguard Worker     p.writeFileDescriptor(STDIN_FILENO, false /*takeOwnership*/);
140*38e8c45fSAndroid Build Coastguard Worker     p.writeInt32(4);
141*38e8c45fSAndroid Build Coastguard Worker 
142*38e8c45fSAndroid Build Coastguard Worker     auto ret = p.debugReadAllFileDescriptors();
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(ret.size(), 2);
145*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(ret[0], STDOUT_FILENO);
146*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(ret[1], STDIN_FILENO);
147*38e8c45fSAndroid Build Coastguard Worker }
148*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,AppendFromEmpty)149*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, AppendFromEmpty) {
150*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
151*38e8c45fSAndroid Build Coastguard Worker     Parcel p2;
152*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(2);
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, p1.appendFrom(&p2, 0, p2.dataSize()));
155*38e8c45fSAndroid Build Coastguard Worker 
156*38e8c45fSAndroid Build Coastguard Worker     p1.setDataPosition(0);
157*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.readInt32());
158*38e8c45fSAndroid Build Coastguard Worker 
159*38e8c45fSAndroid Build Coastguard Worker     p2.setDataPosition(0);
160*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p2.readInt32());
161*38e8c45fSAndroid Build Coastguard Worker }
162*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,AppendPlainData)163*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, AppendPlainData) {
164*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
165*38e8c45fSAndroid Build Coastguard Worker     p1.writeInt32(1);
166*38e8c45fSAndroid Build Coastguard Worker     Parcel p2;
167*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(2);
168*38e8c45fSAndroid Build Coastguard Worker 
169*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, p1.appendFrom(&p2, 0, p2.dataSize()));
170*38e8c45fSAndroid Build Coastguard Worker 
171*38e8c45fSAndroid Build Coastguard Worker     p1.setDataPosition(0);
172*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1, p1.readInt32());
173*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.readInt32());
174*38e8c45fSAndroid Build Coastguard Worker 
175*38e8c45fSAndroid Build Coastguard Worker     p2.setDataPosition(0);
176*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p2.readInt32());
177*38e8c45fSAndroid Build Coastguard Worker }
178*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,AppendPlainDataPartial)179*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, AppendPlainDataPartial) {
180*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
181*38e8c45fSAndroid Build Coastguard Worker     p1.writeInt32(1);
182*38e8c45fSAndroid Build Coastguard Worker     Parcel p2;
183*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(2);
184*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(3);
185*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(4);
186*38e8c45fSAndroid Build Coastguard Worker 
187*38e8c45fSAndroid Build Coastguard Worker     // only copy 8 bytes (two int32's worth)
188*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, p1.appendFrom(&p2, 0, 8));
189*38e8c45fSAndroid Build Coastguard Worker 
190*38e8c45fSAndroid Build Coastguard Worker     p1.setDataPosition(0);
191*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1, p1.readInt32());
192*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.readInt32());
193*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(3, p1.readInt32());
194*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(0, p1.readInt32()); // not 4, end of Parcel
195*38e8c45fSAndroid Build Coastguard Worker 
196*38e8c45fSAndroid Build Coastguard Worker     p2.setDataPosition(0);
197*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p2.readInt32());
198*38e8c45fSAndroid Build Coastguard Worker }
199*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,HasBinders)200*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, HasBinders) {
201*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> b1 = sp<BBinder>::make();
202*38e8c45fSAndroid Build Coastguard Worker 
203*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
204*38e8c45fSAndroid Build Coastguard Worker     p1.writeInt32(1);
205*38e8c45fSAndroid Build Coastguard Worker     p1.writeStrongBinder(b1);
206*38e8c45fSAndroid Build Coastguard Worker 
207*38e8c45fSAndroid Build Coastguard Worker     bool result = false;
208*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, p1.hasBinders(&result));
209*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(true, result);
210*38e8c45fSAndroid Build Coastguard Worker 
211*38e8c45fSAndroid Build Coastguard Worker     p1.setDataSize(0); // clear data
212*38e8c45fSAndroid Build Coastguard Worker     result = false;
213*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, p1.hasBinders(&result));
214*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(false, result);
215*38e8c45fSAndroid Build Coastguard Worker     p1.writeStrongBinder(b1); // reset with binder data
216*38e8c45fSAndroid Build Coastguard Worker     result = false;
217*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, p1.hasBinders(&result));
218*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(true, result);
219*38e8c45fSAndroid Build Coastguard Worker 
220*38e8c45fSAndroid Build Coastguard Worker     Parcel p3;
221*38e8c45fSAndroid Build Coastguard Worker     p3.appendFrom(&p1, 0, p1.dataSize());
222*38e8c45fSAndroid Build Coastguard Worker     result = false;
223*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, p1.hasBinders(&result));
224*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(true, result);
225*38e8c45fSAndroid Build Coastguard Worker }
226*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,HasBindersInRange)227*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, HasBindersInRange) {
228*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> b1 = sp<BBinder>::make();
229*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
230*38e8c45fSAndroid Build Coastguard Worker     p1.writeStrongBinder(b1);
231*38e8c45fSAndroid Build Coastguard Worker     bool result = false;
232*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, p1.hasBindersInRange(0, p1.dataSize(), &result));
233*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(true, result);
234*38e8c45fSAndroid Build Coastguard Worker     result = false;
235*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(NO_ERROR, p1.hasBinders(&result));
236*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(true, result);
237*38e8c45fSAndroid Build Coastguard Worker }
238*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,AppendWithBinder)239*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, AppendWithBinder) {
240*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> b1 = sp<BBinder>::make();
241*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> b2 = sp<BBinder>::make();
242*38e8c45fSAndroid Build Coastguard Worker 
243*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
244*38e8c45fSAndroid Build Coastguard Worker     p1.writeInt32(1);
245*38e8c45fSAndroid Build Coastguard Worker     p1.writeStrongBinder(b1);
246*38e8c45fSAndroid Build Coastguard Worker     Parcel p2;
247*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(2);
248*38e8c45fSAndroid Build Coastguard Worker     p2.writeStrongBinder(b2);
249*38e8c45fSAndroid Build Coastguard Worker 
250*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, p1.appendFrom(&p2, 0, p2.dataSize()));
251*38e8c45fSAndroid Build Coastguard Worker 
252*38e8c45fSAndroid Build Coastguard Worker     p1.setDataPosition(0);
253*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1, p1.readInt32());
254*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(b1, p1.readStrongBinder());
255*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.readInt32());
256*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(b2, p1.readStrongBinder());
257*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.objectsCount());
258*38e8c45fSAndroid Build Coastguard Worker 
259*38e8c45fSAndroid Build Coastguard Worker     p2.setDataPosition(0);
260*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p2.readInt32());
261*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(b2, p2.readStrongBinder());
262*38e8c45fSAndroid Build Coastguard Worker }
263*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,AppendWithBinderPartial)264*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, AppendWithBinderPartial) {
265*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> b1 = sp<BBinder>::make();
266*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> b2 = sp<BBinder>::make();
267*38e8c45fSAndroid Build Coastguard Worker 
268*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
269*38e8c45fSAndroid Build Coastguard Worker     p1.writeInt32(1);
270*38e8c45fSAndroid Build Coastguard Worker     p1.writeStrongBinder(b1);
271*38e8c45fSAndroid Build Coastguard Worker     Parcel p2;
272*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(2);
273*38e8c45fSAndroid Build Coastguard Worker     p2.writeStrongBinder(b2);
274*38e8c45fSAndroid Build Coastguard Worker 
275*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, p1.appendFrom(&p2, 0, 8)); // BAD: 4 bytes into strong binder
276*38e8c45fSAndroid Build Coastguard Worker 
277*38e8c45fSAndroid Build Coastguard Worker     p1.setDataPosition(0);
278*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1, p1.readInt32());
279*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(b1, p1.readStrongBinder());
280*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.readInt32());
281*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1935813253, p1.readInt32()); // whatever garbage that is there (ABI)
282*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1, p1.objectsCount());
283*38e8c45fSAndroid Build Coastguard Worker 
284*38e8c45fSAndroid Build Coastguard Worker     p2.setDataPosition(0);
285*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p2.readInt32());
286*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(b2, p2.readStrongBinder());
287*38e8c45fSAndroid Build Coastguard Worker }
288*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,AppendWithFd)289*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, AppendWithFd) {
290*38e8c45fSAndroid Build Coastguard Worker     unique_fd fd1 = unique_fd(dup(0));
291*38e8c45fSAndroid Build Coastguard Worker     unique_fd fd2 = unique_fd(dup(0));
292*38e8c45fSAndroid Build Coastguard Worker 
293*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
294*38e8c45fSAndroid Build Coastguard Worker     p1.writeInt32(1);
295*38e8c45fSAndroid Build Coastguard Worker     p1.writeDupFileDescriptor(0);      // with ownership
296*38e8c45fSAndroid Build Coastguard Worker     p1.writeFileDescriptor(fd1.get()); // without ownership
297*38e8c45fSAndroid Build Coastguard Worker     Parcel p2;
298*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(2);
299*38e8c45fSAndroid Build Coastguard Worker     p2.writeDupFileDescriptor(0);      // with ownership
300*38e8c45fSAndroid Build Coastguard Worker     p2.writeFileDescriptor(fd2.get()); // without ownership
301*38e8c45fSAndroid Build Coastguard Worker 
302*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, p1.appendFrom(&p2, 0, p2.dataSize()));
303*38e8c45fSAndroid Build Coastguard Worker 
304*38e8c45fSAndroid Build Coastguard Worker     p1.setDataPosition(0);
305*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1, p1.readInt32());
306*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
307*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
308*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.readInt32());
309*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
310*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
311*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(4, p1.objectsCount());
312*38e8c45fSAndroid Build Coastguard Worker 
313*38e8c45fSAndroid Build Coastguard Worker     p2.setDataPosition(0);
314*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p2.readInt32());
315*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
316*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
317*38e8c45fSAndroid Build Coastguard Worker }
318*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,AppendWithFdPartial)319*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, AppendWithFdPartial) {
320*38e8c45fSAndroid Build Coastguard Worker     unique_fd fd1 = unique_fd(dup(0));
321*38e8c45fSAndroid Build Coastguard Worker     unique_fd fd2 = unique_fd(dup(0));
322*38e8c45fSAndroid Build Coastguard Worker 
323*38e8c45fSAndroid Build Coastguard Worker     Parcel p1;
324*38e8c45fSAndroid Build Coastguard Worker     p1.writeInt32(1);
325*38e8c45fSAndroid Build Coastguard Worker     p1.writeDupFileDescriptor(0);      // with ownership
326*38e8c45fSAndroid Build Coastguard Worker     p1.writeFileDescriptor(fd1.get()); // without ownership
327*38e8c45fSAndroid Build Coastguard Worker     Parcel p2;
328*38e8c45fSAndroid Build Coastguard Worker     p2.writeInt32(2);
329*38e8c45fSAndroid Build Coastguard Worker     p2.writeDupFileDescriptor(0);      // with ownership
330*38e8c45fSAndroid Build Coastguard Worker     p2.writeFileDescriptor(fd2.get()); // without ownership
331*38e8c45fSAndroid Build Coastguard Worker 
332*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, p1.appendFrom(&p2, 0, 8)); // BAD: 4 bytes into binder
333*38e8c45fSAndroid Build Coastguard Worker 
334*38e8c45fSAndroid Build Coastguard Worker     p1.setDataPosition(0);
335*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1, p1.readInt32());
336*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
337*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
338*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.readInt32());
339*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(1717840517, p1.readInt32()); // whatever garbage that is there (ABI)
340*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p1.objectsCount());
341*38e8c45fSAndroid Build Coastguard Worker 
342*38e8c45fSAndroid Build Coastguard Worker     p2.setDataPosition(0);
343*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(2, p2.readInt32());
344*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
345*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(-1, p1.readFileDescriptor());
346*38e8c45fSAndroid Build Coastguard Worker }
347*38e8c45fSAndroid Build Coastguard Worker 
348*38e8c45fSAndroid Build Coastguard Worker // Tests a second operation results in a parcel at the same location as it
349*38e8c45fSAndroid Build Coastguard Worker // started.
parcelOpSameLength(const std::function<void (Parcel *)> & a,const std::function<void (Parcel *)> & b)350*38e8c45fSAndroid Build Coastguard Worker void parcelOpSameLength(const std::function<void(Parcel*)>& a, const std::function<void(Parcel*)>& b) {
351*38e8c45fSAndroid Build Coastguard Worker     Parcel p;
352*38e8c45fSAndroid Build Coastguard Worker     a(&p);
353*38e8c45fSAndroid Build Coastguard Worker     size_t end = p.dataPosition();
354*38e8c45fSAndroid Build Coastguard Worker     p.setDataPosition(0);
355*38e8c45fSAndroid Build Coastguard Worker     b(&p);
356*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(end, p.dataPosition());
357*38e8c45fSAndroid Build Coastguard Worker }
358*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,InverseInterfaceToken)359*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, InverseInterfaceToken) {
360*38e8c45fSAndroid Build Coastguard Worker     const String16 token = String16("asdf");
361*38e8c45fSAndroid Build Coastguard Worker     parcelOpSameLength([&] (Parcel* p) {
362*38e8c45fSAndroid Build Coastguard Worker         p->writeInterfaceToken(token);
363*38e8c45fSAndroid Build Coastguard Worker     }, [&] (Parcel* p) {
364*38e8c45fSAndroid Build Coastguard Worker         EXPECT_TRUE(p->enforceInterface(token, IPCThreadState::self()));
365*38e8c45fSAndroid Build Coastguard Worker     });
366*38e8c45fSAndroid Build Coastguard Worker }
367*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,Utf8FromUtf16Read)368*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, Utf8FromUtf16Read) {
369*38e8c45fSAndroid Build Coastguard Worker     const char* token = "asdf";
370*38e8c45fSAndroid Build Coastguard Worker     parcelOpSameLength([&] (Parcel* p) {
371*38e8c45fSAndroid Build Coastguard Worker         p->writeString16(String16(token));
372*38e8c45fSAndroid Build Coastguard Worker     }, [&] (Parcel* p) {
373*38e8c45fSAndroid Build Coastguard Worker         std::string s;
374*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(OK, p->readUtf8FromUtf16(&s));
375*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(token, s);
376*38e8c45fSAndroid Build Coastguard Worker     });
377*38e8c45fSAndroid Build Coastguard Worker }
378*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,Utf8AsUtf16Write)379*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, Utf8AsUtf16Write) {
380*38e8c45fSAndroid Build Coastguard Worker     std::string token = "asdf";
381*38e8c45fSAndroid Build Coastguard Worker     parcelOpSameLength([&] (Parcel* p) {
382*38e8c45fSAndroid Build Coastguard Worker         p->writeUtf8AsUtf16(token);
383*38e8c45fSAndroid Build Coastguard Worker     }, [&] (Parcel* p) {
384*38e8c45fSAndroid Build Coastguard Worker         String16 s;
385*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(OK, p->readString16(&s));
386*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(s, String16(token.c_str()));
387*38e8c45fSAndroid Build Coastguard Worker     });
388*38e8c45fSAndroid Build Coastguard Worker }
389*38e8c45fSAndroid Build Coastguard Worker 
390*38e8c45fSAndroid Build Coastguard Worker template <typename T>
391*38e8c45fSAndroid Build Coastguard Worker using readFunc = status_t (Parcel::*)(T* out) const;
392*38e8c45fSAndroid Build Coastguard Worker template <typename T>
393*38e8c45fSAndroid Build Coastguard Worker using writeFunc = status_t (Parcel::*)(const T& in);
394*38e8c45fSAndroid Build Coastguard Worker template <typename T>
395*38e8c45fSAndroid Build Coastguard Worker using copyWriteFunc = status_t (Parcel::*)(T in);
396*38e8c45fSAndroid Build Coastguard Worker 
397*38e8c45fSAndroid Build Coastguard Worker template <typename T, typename WRITE_FUNC>
readWriteInverse(std::vector<T> && ts,readFunc<T> r,WRITE_FUNC w)398*38e8c45fSAndroid Build Coastguard Worker void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, WRITE_FUNC w) {
399*38e8c45fSAndroid Build Coastguard Worker     for (const T& value : ts) {
400*38e8c45fSAndroid Build Coastguard Worker         parcelOpSameLength([&] (Parcel* p) {
401*38e8c45fSAndroid Build Coastguard Worker             (*p.*w)(value);
402*38e8c45fSAndroid Build Coastguard Worker         }, [&] (Parcel* p) {
403*38e8c45fSAndroid Build Coastguard Worker             T outValue;
404*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(OK, (*p.*r)(&outValue));
405*38e8c45fSAndroid Build Coastguard Worker             EXPECT_EQ(value, outValue);
406*38e8c45fSAndroid Build Coastguard Worker         });
407*38e8c45fSAndroid Build Coastguard Worker     }
408*38e8c45fSAndroid Build Coastguard Worker }
409*38e8c45fSAndroid Build Coastguard Worker 
410*38e8c45fSAndroid Build Coastguard Worker template <typename T>
readWriteInverse(std::vector<T> && ts,readFunc<T> r,writeFunc<T> w)411*38e8c45fSAndroid Build Coastguard Worker void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, writeFunc<T> w) {
412*38e8c45fSAndroid Build Coastguard Worker     readWriteInverse<T, writeFunc<T>>(std::move(ts), r, w);
413*38e8c45fSAndroid Build Coastguard Worker }
414*38e8c45fSAndroid Build Coastguard Worker template <typename T>
readWriteInverse(std::vector<T> && ts,readFunc<T> r,copyWriteFunc<T> w)415*38e8c45fSAndroid Build Coastguard Worker void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, copyWriteFunc<T> w) {
416*38e8c45fSAndroid Build Coastguard Worker     readWriteInverse<T, copyWriteFunc<T>>(std::move(ts), r, w);
417*38e8c45fSAndroid Build Coastguard Worker }
418*38e8c45fSAndroid Build Coastguard Worker 
419*38e8c45fSAndroid Build Coastguard Worker #define TEST_READ_WRITE_INVERSE(type, name, ...) \
420*38e8c45fSAndroid Build Coastguard Worker     TEST(Parcel, Inverse##name) { \
421*38e8c45fSAndroid Build Coastguard Worker         readWriteInverse<type>(__VA_ARGS__, &Parcel::read##name, &Parcel::write##name); \
422*38e8c45fSAndroid Build Coastguard Worker     }
423*38e8c45fSAndroid Build Coastguard Worker 
424*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(int32_t, Int32, {-2, -1, 0, 1, 2});
425*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(uint32_t, Uint32, {0, 1, 2});
426*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(int64_t, Int64, {-2, -1, 0, 1, 2});
427*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(uint64_t, Uint64, {0, 1, 2});
428*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(float, Float, {-1.0f, 0.0f, 3.14f});
429*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(double, Double, {-1.0, 0.0, 3.14});
430*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(bool, Bool, {true, false});
431*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(char16_t, Char, {u'a', u'\0'});
432*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(int8_t, Byte, {-1, 0, 1});
433*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(String8, String8, {String8(), String8("a"), String8("asdf")});
434*38e8c45fSAndroid Build Coastguard Worker TEST_READ_WRITE_INVERSE(String16, String16, {String16(), String16("a"), String16("asdf")});
435*38e8c45fSAndroid Build Coastguard Worker 
TEST(Parcel,GetOpenAshmemSize)436*38e8c45fSAndroid Build Coastguard Worker TEST(Parcel, GetOpenAshmemSize) {
437*38e8c45fSAndroid Build Coastguard Worker     constexpr size_t kSize = 1024;
438*38e8c45fSAndroid Build Coastguard Worker     constexpr size_t kCount = 3;
439*38e8c45fSAndroid Build Coastguard Worker 
440*38e8c45fSAndroid Build Coastguard Worker     Parcel p;
441*38e8c45fSAndroid Build Coastguard Worker 
442*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < kCount; i++) {
443*38e8c45fSAndroid Build Coastguard Worker         int fd = ashmem_create_region("test-getOpenAshmemSize", kSize);
444*38e8c45fSAndroid Build Coastguard Worker         ASSERT_GE(fd, 0);
445*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(OK, p.writeFileDescriptor(fd, true /* take ownership */));
446*38e8c45fSAndroid Build Coastguard Worker 
447*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ((kSize * (i + 1)), p.getOpenAshmemSize());
448*38e8c45fSAndroid Build Coastguard Worker     }
449*38e8c45fSAndroid Build Coastguard Worker }
450