1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <aidl/aidl/TestStableLargeParcelable.h>
18 #include <aidl/aidl/TestStableLargeParcelableVector.h>
19 #include <aidl/aidl/TestStableParcelable.h>
20 #include <android/binder_auto_utils.h>
21 #include <android/binder_parcel.h>
22 #include <gtest/gtest.h>
23
24 #include <LargeParcelable.h>
25 #include <LargeParcelableBase.h>
26 #include <LargeParcelableVector.h>
27
28 #include <algorithm>
29 #include <vector>
30
31 namespace {
32
33 using ::aidl::aidl::TestStableLargeParcelable;
34 using ::aidl::aidl::TestStableLargeParcelableVector;
35 using ::aidl::aidl::TestStableParcelable;
36 using ::android::automotive::car_binder_lib::LargeParcelable;
37 using ::android::automotive::car_binder_lib::LargeParcelableBase;
38 using ::android::automotive::car_binder_lib::LargeParcelableVector;
39 using ::ndk::ScopedAParcel;
40 using ::ndk::ScopedFileDescriptor;
41
42 int TEST_VALUE = 1234;
43 size_t VECTOR_SIZE = 16;
44
createTestStableParcelable(size_t dataSize)45 std::unique_ptr<TestStableParcelable> createTestStableParcelable(size_t dataSize) {
46 std::unique_ptr<TestStableParcelable> p(new TestStableParcelable);
47 p->bytes.resize(dataSize);
48 std::fill(p->bytes.begin(), p->bytes.end(), 0x7f);
49 p->value = TEST_VALUE;
50 return p;
51 }
52
createTestStableParcelableVector(size_t dataSize)53 std::vector<TestStableParcelable> createTestStableParcelableVector(size_t dataSize) {
54 std::vector<TestStableParcelable> p;
55 size_t VECTOR_SIZE = 16;
56 for (size_t i = 0; i < VECTOR_SIZE; i++) {
57 p.push_back(*createTestStableParcelable(dataSize / VECTOR_SIZE));
58 }
59 return p;
60 }
61
checkTestStableParcelable(const TestStableParcelable * p,size_t dataSize)62 void checkTestStableParcelable(const TestStableParcelable* p, size_t dataSize) {
63 ASSERT_EQ(dataSize, p->bytes.size());
64 for (size_t i = 0; i < dataSize; i++) {
65 ASSERT_EQ(0x7f, p->bytes[i]);
66 }
67 ASSERT_EQ(TEST_VALUE, p->value);
68 }
69
checkTestStableParcelableVector(const std::vector<TestStableParcelable> * p,size_t dataSize)70 void checkTestStableParcelableVector(const std::vector<TestStableParcelable>* p, size_t dataSize) {
71 ASSERT_EQ(VECTOR_SIZE, p->size());
72 for (size_t i = 0; i < VECTOR_SIZE; i++) {
73 checkTestStableParcelable(&((*p)[i]), dataSize / VECTOR_SIZE);
74 }
75 }
76
testWrapStableAidlWriteReadPayload(size_t dataSize)77 void testWrapStableAidlWriteReadPayload(size_t dataSize) {
78 std::unique_ptr<TestStableParcelable> p = createTestStableParcelable(dataSize);
79
80 LargeParcelable sendData(std::move(p));
81 ScopedAParcel parcel(AParcel_create());
82 binder_status_t status;
83 status = sendData.writeToParcel(parcel.get());
84
85 ASSERT_EQ(status, STATUS_OK);
86
87 // Set the parcel to start from 0 because we need to read from 0.
88 AParcel_setDataPosition(parcel.get(), 0);
89
90 LargeParcelable<TestStableParcelable> receiveData;
91 status = receiveData.readFromParcel(parcel.get());
92
93 ASSERT_EQ(status, STATUS_OK);
94
95 ASSERT_TRUE(receiveData.getParcelable().has_value());
96
97 const TestStableParcelable* getP = receiveData.getParcelable().value();
98
99 checkTestStableParcelable(getP, dataSize);
100 }
101
TEST(LargeParcelableTest,LargeParcelableWrapStableAidlWriteReadSmallPayload)102 TEST(LargeParcelableTest, LargeParcelableWrapStableAidlWriteReadSmallPayload) {
103 testWrapStableAidlWriteReadPayload(1024);
104 }
105
TEST(LargeParcelableTest,LargeParcelableWrapStableAidlWriteReadLargePayload)106 TEST(LargeParcelableTest, LargeParcelableWrapStableAidlWriteReadLargePayload) {
107 testWrapStableAidlWriteReadPayload(8 * 1024);
108 }
109
TEST(LargeParcelableTest,WrapStableAidlReuseSharedMemoryFile)110 TEST(LargeParcelableTest, WrapStableAidlReuseSharedMemoryFile) {
111 size_t dataSize = 8 * 1024;
112 std::unique_ptr<TestStableParcelable> p = createTestStableParcelable(dataSize);
113
114 LargeParcelable sendData(std::move(p));
115
116 ScopedAParcel parcel(AParcel_create());
117 binder_status_t status = sendData.writeToParcel(parcel.get());
118
119 ASSERT_EQ(status, STATUS_OK);
120
121 ScopedAParcel parcel2(AParcel_create());
122 status = sendData.writeToParcel(parcel2.get());
123
124 ASSERT_EQ(status, STATUS_OK);
125
126 // Set the parcel to start from 0 because we need to read from 0.
127 AParcel_setDataPosition(parcel2.get(), 0);
128
129 LargeParcelable<TestStableParcelable> receiveData;
130 status = receiveData.readFromParcel(parcel2.get());
131
132 ASSERT_EQ(status, STATUS_OK);
133
134 ASSERT_TRUE(receiveData.getParcelable().has_value());
135 const TestStableParcelable* getP = receiveData.getParcelable().value();
136
137 checkTestStableParcelable(getP, dataSize);
138 }
139
testParcelableToStableLargeParcelable(size_t dataSize)140 void testParcelableToStableLargeParcelable(size_t dataSize) {
141 std::unique_ptr<TestStableParcelable> p = createTestStableParcelable(dataSize);
142
143 TestStableLargeParcelable largeP;
144 largeP.payload = *p;
145 auto result = LargeParcelableBase::parcelableToStableLargeParcelable(largeP);
146
147 ASSERT_TRUE(result.ok()) << result.error();
148
149 TestStableLargeParcelable out;
150 if (result.value() == nullptr) {
151 out.payload = *p;
152 } else {
153 out.sharedMemoryFd = std::move(*result.value());
154 }
155
156 ScopedAParcel parcel(AParcel_create());
157 binder_status_t status = out.writeToParcel(parcel.get());
158
159 ASSERT_EQ(status, STATUS_OK);
160
161 // Set the parcel to start from 0 because we need to read from 0.
162 AParcel_setDataPosition(parcel.get(), 0);
163
164 // The parcel generated from StableLargeParcelable should be compatible with LargeParcelable.
165 // We use LargeParcelable based on TestStableParcelable to read from the generated parcel.
166 LargeParcelable<TestStableParcelable> receiveData;
167 status = receiveData.readFromParcel(parcel.get());
168
169 ASSERT_EQ(status, STATUS_OK);
170
171 ASSERT_TRUE(receiveData.getParcelable().has_value());
172 const TestStableParcelable* getP = receiveData.getParcelable().value();
173
174 checkTestStableParcelable(getP, dataSize);
175 }
176
TEST(LargeParcelableTest,ParcelableToStableLargeParcelableSmallPayload)177 TEST(LargeParcelableTest, ParcelableToStableLargeParcelableSmallPayload) {
178 testParcelableToStableLargeParcelable(1024);
179 }
180
TEST(LargeParcelableTest,ParcelableToStableLargeParcelableLargePayload)181 TEST(LargeParcelableTest, ParcelableToStableLargeParcelableLargePayload) {
182 testParcelableToStableLargeParcelable(8 * 1024);
183 }
184
testStableLargeParcelableToParcelable(size_t dataSize)185 void testStableLargeParcelableToParcelable(size_t dataSize) {
186 std::unique_ptr<TestStableParcelable> p = createTestStableParcelable(dataSize);
187
188 // Use LargeParcelable to write to a parcel. Since it is compatible with StableLargeParcelable,
189 // it should be able to be parsed.
190 LargeParcelable sendData(std::move(p));
191 ScopedAParcel parcel(AParcel_create());
192 binder_status_t status;
193 status = sendData.writeToParcel(parcel.get());
194
195 ASSERT_EQ(status, STATUS_OK);
196
197 // Set the parcel to start from 0 because we need to read from 0.
198 AParcel_setDataPosition(parcel.get(), 0);
199
200 TestStableLargeParcelable largeParcelable;
201 status = largeParcelable.readFromParcel(parcel.get());
202
203 ASSERT_EQ(status, STATUS_OK);
204
205 // Convert the StableLargeParcelable back to the original parcelable.
206 auto result = LargeParcelableBase::stableLargeParcelableToParcelable(largeParcelable);
207
208 ASSERT_TRUE(result.ok()) << result.error();
209
210 const TestStableLargeParcelable* out = result.value().getObject();
211 ASSERT_TRUE(out->payload.has_value());
212 checkTestStableParcelable(&(out->payload.value()), dataSize);
213 }
214
TEST(LargeParcelableTest,StableLargeParcelableToParcelableSmallPayload)215 TEST(LargeParcelableTest, StableLargeParcelableToParcelableSmallPayload) {
216 testStableLargeParcelableToParcelable(1024);
217 }
218
TEST(LargeParcelableTest,StableLargeParcelableToParcelableLargePayload)219 TEST(LargeParcelableTest, StableLargeParcelableToParcelableLargePayload) {
220 testStableLargeParcelableToParcelable(8 * 1024);
221 }
222
testParcelableToStableLargeParcelableBackToParcelable(size_t dataSize)223 void testParcelableToStableLargeParcelableBackToParcelable(size_t dataSize) {
224 std::unique_ptr<TestStableParcelable> p = createTestStableParcelable(dataSize);
225
226 TestStableLargeParcelable largeP;
227 largeP.payload = *p;
228 auto result1 = LargeParcelableBase::parcelableToStableLargeParcelable(largeP);
229
230 ASSERT_TRUE(result1.ok()) << result1.error();
231
232 TestStableLargeParcelable intermediate;
233 if (result1.value() == nullptr) {
234 intermediate.payload = std::move(*p);
235 } else {
236 intermediate.sharedMemoryFd = std::move(*result1.value());
237 }
238
239 auto result2 = LargeParcelableBase::stableLargeParcelableToParcelable(intermediate);
240
241 ASSERT_TRUE(result2.ok()) << result2.error();
242
243 const TestStableLargeParcelable* out = result2.value().getObject();
244 ASSERT_TRUE(out->payload.has_value());
245 checkTestStableParcelable(&(out->payload.value()), dataSize);
246 }
247
TEST(LargeParcelableTest,ParcelableToStableLargeParcelableBackToParcelableSmallPayload)248 TEST(LargeParcelableTest, ParcelableToStableLargeParcelableBackToParcelableSmallPayload) {
249 testParcelableToStableLargeParcelableBackToParcelable(1024);
250 }
251
TEST(LargeParcelableTest,ParcelableToStableLargeParcelableBackToParcelableLargePayload)252 TEST(LargeParcelableTest, ParcelableToStableLargeParcelableBackToParcelableLargePayload) {
253 testParcelableToStableLargeParcelableBackToParcelable(8 * 1024);
254 }
255
testWrapStableAidlVectorWriteReadPayload(size_t dataSize)256 void testWrapStableAidlVectorWriteReadPayload(size_t dataSize) {
257 std::vector<TestStableParcelable> p = createTestStableParcelableVector(dataSize);
258
259 LargeParcelableVector sendData(std::move(p));
260 ScopedAParcel parcel(AParcel_create());
261 binder_status_t status;
262 status = sendData.writeToParcel(parcel.get());
263
264 ASSERT_EQ(status, STATUS_OK);
265
266 // Set the parcel to start from 0 because we need to read from 0.
267 AParcel_setDataPosition(parcel.get(), 0);
268
269 LargeParcelableVector<TestStableParcelable> receiveData;
270 status = receiveData.readFromParcel(parcel.get());
271
272 ASSERT_EQ(status, STATUS_OK);
273
274 ASSERT_TRUE(receiveData.getParcelables().has_value());
275 const std::vector<TestStableParcelable>* getP = receiveData.getParcelables().value();
276
277 checkTestStableParcelableVector(getP, dataSize);
278 }
279
TEST(LargeParcelableTest,LargeParcelableWrapStableAidlVectorWriteReadSmallPayload)280 TEST(LargeParcelableTest, LargeParcelableWrapStableAidlVectorWriteReadSmallPayload) {
281 testWrapStableAidlVectorWriteReadPayload(1024);
282 }
283
TEST(LargeParcelableTest,LargeParcelableWrapStableAidlVectorWriteReadLargePayload)284 TEST(LargeParcelableTest, LargeParcelableWrapStableAidlVectorWriteReadLargePayload) {
285 testWrapStableAidlVectorWriteReadPayload(8 * 1024);
286 }
287
testParcelableVectorToStableLargeParcelable(size_t dataSize)288 void testParcelableVectorToStableLargeParcelable(size_t dataSize) {
289 std::vector<TestStableParcelable> p = createTestStableParcelableVector(dataSize);
290 TestStableLargeParcelableVector largeP;
291 largeP.payload = p;
292
293 auto result = LargeParcelableBase::parcelableToStableLargeParcelable(largeP);
294
295 ASSERT_TRUE(result.ok()) << result.error();
296
297 TestStableLargeParcelableVector out;
298 if (result.value() == nullptr) {
299 out.payload = std::move(p);
300 } else {
301 out.sharedMemoryFd = std::move(*result.value());
302 }
303
304 ScopedAParcel parcel(AParcel_create());
305 binder_status_t status = out.writeToParcel(parcel.get());
306
307 ASSERT_EQ(status, STATUS_OK);
308
309 // Set the parcel to start from 0 because we need to read from 0.
310 AParcel_setDataPosition(parcel.get(), 0);
311
312 // The parcel generated from StableLargeParcelable should be compatible with LargeParcelable.
313 // We use LargeParcelable based on TestStableParcelable to read from the generated parcel.
314 LargeParcelableVector<TestStableParcelable> receiveData;
315 status = receiveData.readFromParcel(parcel.get());
316
317 ASSERT_EQ(status, STATUS_OK);
318
319 ASSERT_TRUE(receiveData.getParcelables().has_value());
320 const std::vector<TestStableParcelable>* getP = receiveData.getParcelables().value();
321
322 checkTestStableParcelableVector(getP, dataSize);
323 }
324
TEST(LargeParcelableTest,ParcelableVectorToStableLargeParcelableSmallPayload)325 TEST(LargeParcelableTest, ParcelableVectorToStableLargeParcelableSmallPayload) {
326 testParcelableVectorToStableLargeParcelable(1024);
327 }
328
TEST(LargeParcelableTest,ParcelableVectorToStableLargeParcelableLargePayload)329 TEST(LargeParcelableTest, ParcelableVectorToStableLargeParcelableLargePayload) {
330 testParcelableVectorToStableLargeParcelable(8 * 1024);
331 }
332
testStableLargeParcelableToParcelableVector(size_t dataSize)333 void testStableLargeParcelableToParcelableVector(size_t dataSize) {
334 std::vector<TestStableParcelable> p = createTestStableParcelableVector(dataSize);
335
336 // Use LargeParcelable to write to a parcel. Since it is compatible with StableLargeParcelable,
337 // it should be able to be parsed.
338 LargeParcelableVector sendData(std::move(p));
339 ScopedAParcel parcel(AParcel_create());
340 binder_status_t status;
341 status = sendData.writeToParcel(parcel.get());
342
343 ASSERT_EQ(status, STATUS_OK);
344
345 // Set the parcel to start from 0 because we need to read from 0.
346 AParcel_setDataPosition(parcel.get(), 0);
347
348 TestStableLargeParcelableVector largeParcelable;
349 status = largeParcelable.readFromParcel(parcel.get());
350
351 ASSERT_EQ(status, STATUS_OK);
352
353 std::vector<TestStableParcelable> out;
354 // Convert the StableLargeParcelable back to the original parcelable.
355 auto result = LargeParcelableBase::stableLargeParcelableToParcelable(largeParcelable);
356
357 ASSERT_TRUE(result.ok()) << result.error();
358
359 checkTestStableParcelableVector(&(result.value().getObject()->payload), dataSize);
360 }
361
TEST(LargeParcelableTest,StableLargeParcelableToParcelableVectorSmallPayload)362 TEST(LargeParcelableTest, StableLargeParcelableToParcelableVectorSmallPayload) {
363 testStableLargeParcelableToParcelableVector(1024);
364 }
365
TEST(LargeParcelableTest,StableLargeParcelableToParcelableVectorLargePayload)366 TEST(LargeParcelableTest, StableLargeParcelableToParcelableVectorLargePayload) {
367 testStableLargeParcelableToParcelableVector(8 * 1024);
368 }
369
testParcelableVectorToStableLargeParcelableBackToParcelableVector(size_t dataSize)370 void testParcelableVectorToStableLargeParcelableBackToParcelableVector(size_t dataSize) {
371 std::vector<TestStableParcelable> p = createTestStableParcelableVector(dataSize);
372 TestStableLargeParcelableVector largeP;
373 largeP.payload = p;
374
375 auto result1 = LargeParcelableBase::parcelableToStableLargeParcelable(largeP);
376
377 ASSERT_TRUE(result1.ok()) << result1.error();
378
379 TestStableLargeParcelableVector intermediate;
380 if (result1.value() == nullptr) {
381 intermediate.payload = std::move(p);
382 } else {
383 intermediate.sharedMemoryFd = std::move(*result1.value());
384 }
385
386 auto result2 = LargeParcelableBase::stableLargeParcelableToParcelable(intermediate);
387
388 ASSERT_TRUE(result2.ok()) << result2.error();
389
390 checkTestStableParcelableVector(&(result2.value().getObject()->payload), dataSize);
391 }
392
TEST(LargeParcelableTest,ParcelableVectorToStableLargeParcelableBackToParcelableVectorSmallPayload)393 TEST(LargeParcelableTest,
394 ParcelableVectorToStableLargeParcelableBackToParcelableVectorSmallPayload) {
395 testParcelableVectorToStableLargeParcelableBackToParcelableVector(1024);
396 }
397
TEST(LargeParcelableTest,ParcelableVectorToStableLargeParcelableBackToParcelableVectorLargePayload)398 TEST(LargeParcelableTest,
399 ParcelableVectorToStableLargeParcelableBackToParcelableVectorLargePayload) {
400 testParcelableVectorToStableLargeParcelableBackToParcelableVector(8 * 1024);
401 }
402
403 } // namespace
404