1 /*
2 * Copyright (C) 2018 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 #define LOG_TAG "Cts-NdkBinderTest"
17
18 #include <android/binder_ibinder.h>
19 #include <android/binder_parcel.h>
20 #include <android/binder_parcel_utils.h>
21 #include <android/log.h>
22 #include <gtest/gtest.h>
23
24 #include "utilities.h"
25
26 #include <limits>
27 #include <vector>
28
29 class NdkBinderTest_AParcel : public NdkBinderTest {};
30
31 template <typename T, typename Enable = void>
32 struct WriteFrom {
33 using type = const T;
34 };
35 template <>
36 struct WriteFrom<AStatus*> {
37 // not 'const T' = 'AStatus* const' where T = AStatus*.
38 using type = const AStatus*;
39 };
40
41 template <typename T>
NdkBinderSenseOfEquality(T a,T b)42 bool NdkBinderSenseOfEquality(T a, T b) {
43 return a == b;
44 }
45 template <>
NdkBinderSenseOfEquality(const AStatus * a,const AStatus * b)46 bool NdkBinderSenseOfEquality<const AStatus*>(const AStatus* a,
47 const AStatus* b) {
48 if (a == b) return true;
49
50 return AStatus_isOk(a) == AStatus_isOk(b) &&
51 AStatus_getExceptionCode(a) == AStatus_getExceptionCode(b) &&
52 AStatus_getServiceSpecificError(a) ==
53 AStatus_getServiceSpecificError(b) &&
54 AStatus_getStatus(a) == AStatus_getStatus(b) &&
55 std::string(AStatus_getMessage(a)) == AStatus_getMessage(b);
56 }
57 template <>
NdkBinderSenseOfEquality(AStatus * a,AStatus * b)58 bool NdkBinderSenseOfEquality<AStatus*>(AStatus* a, AStatus* b) {
59 return NdkBinderSenseOfEquality<const AStatus*>(a, b);
60 }
61
62 template <typename T>
castForStream(T val)63 auto castForStream(T val) {
64 return val;
65 }
66
67 template <>
castForStream(char16_t val)68 auto castForStream(char16_t val) {
69 return static_cast<int>(val);
70 }
71
72 // These reads and writes an array of possible values all of the same type.
73 template <typename T,
74 binder_status_t (*write)(AParcel*, typename WriteFrom<T>::type),
75 binder_status_t (*read)(const AParcel*, T*)>
ExpectInOut(std::vector<T> in)76 void ExpectInOut(std::vector<T> in) {
77 AIBinder* binder = SampleData::newBinder(
78 [](transaction_code_t, const AParcel* in, AParcel* out) {
79 T readTarget = {};
80 EXPECT_OK(read(in, &readTarget));
81 EXPECT_OK(write(out, readTarget));
82 return STATUS_OK;
83 },
84 ExpectLifetimeTransactions(in.size()));
85
86 for (const auto& value : in) {
87 EXPECT_OK(SampleData::transact(
88 binder, kCode,
89 [&](AParcel* in) {
90 EXPECT_OK(write(in, value));
91 return STATUS_OK;
92 },
93 [&](const AParcel* out) {
94 T readTarget = {};
95 EXPECT_OK(read(out, &readTarget));
96 EXPECT_TRUE(NdkBinderSenseOfEquality<T>(value, readTarget))
97 << castForStream(value) << " is not " << castForStream(readTarget);
98 return STATUS_OK;
99 }));
100 }
101
102 AIBinder_decStrong(binder);
103 }
104
105 template <typename T,
106 binder_status_t (*write)(AParcel*, typename WriteFrom<T>::type),
107 binder_status_t (*read)(const AParcel*, T*)>
ExpectInOutMinMax()108 void ExpectInOutMinMax() {
109 ExpectInOut<T, write, read>(
110 {std::numeric_limits<T>::min(), std::numeric_limits<T>::max()});
111 }
112
TEST_F(NdkBinderTest_AParcel,BindersInMustComeOut)113 TEST_F(NdkBinderTest_AParcel, BindersInMustComeOut) {
114 AIBinder* binder = SampleData::newBinder();
115
116 ExpectInOut<AIBinder*, AParcel_writeStrongBinder, AParcel_readStrongBinder>(
117 {binder});
118 // copy which is read when this binder is sent in a transaction to this
119 // process
120 AIBinder_decStrong(binder);
121 // copy which is read when this binder is returned in a transaction within
122 // this same process and is read again
123 AIBinder_decStrong(binder);
124
125 ExpectInOut<AIBinder*, AParcel_writeStrongBinder, AParcel_readStrongBinder>(
126 {nullptr, binder});
127 // copy which is read when this binder is sent in a transaction to this
128 // process
129 AIBinder_decStrong(binder);
130 // copy which is read when this binder is returned in a transaction within
131 // this same process and is read again
132 AIBinder_decStrong(binder);
133
134 AIBinder_decStrong(binder);
135 }
136
TEST_F(NdkBinderTest_AParcel,StatusesInMustComeOut)137 TEST_F(NdkBinderTest_AParcel, StatusesInMustComeOut) {
138 // This does not clean up status objects.
139 ExpectInOut<AStatus*, AParcel_writeStatusHeader, AParcel_readStatusHeader>({
140 AStatus_newOk(),
141 AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT),
142 AStatus_fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
143 "+++++++++[->++++++++<]>.+."),
144 AStatus_fromServiceSpecificError(1776),
145 AStatus_fromServiceSpecificErrorWithMessage(0xBEA, "utiful!"),
146 });
147 }
148
TEST_F(NdkBinderTest_AParcel,LowLevelErrorsHaveNoStatusHeader)149 TEST_F(NdkBinderTest_AParcel, LowLevelErrorsHaveNoStatusHeader) {
150 AIBinder* binder =
151 SampleData::newBinder(nullptr, ExpectLifetimeTransactions(0));
152
153 EXPECT_EQ(
154 STATUS_UNKNOWN_ERROR,
155 SampleData::transact(binder, kCode, [&](AParcel* in) {
156 AStatus* status = nullptr;
157
158 status = AStatus_fromExceptionCode(EX_TRANSACTION_FAILED);
159 EXPECT_EQ(STATUS_FAILED_TRANSACTION,
160 AParcel_writeStatusHeader(in, status));
161 AStatus_delete(status);
162
163 status = AStatus_fromExceptionCodeWithMessage(EX_TRANSACTION_FAILED,
164 "something or other");
165 EXPECT_EQ(STATUS_FAILED_TRANSACTION,
166 AParcel_writeStatusHeader(in, status));
167 AStatus_delete(status);
168
169 status = AStatus_fromStatus(STATUS_UNKNOWN_ERROR);
170 EXPECT_EQ(STATUS_UNKNOWN_ERROR, AParcel_writeStatusHeader(in, status));
171 AStatus_delete(status);
172
173 status = AStatus_fromStatus(STATUS_BAD_VALUE);
174 EXPECT_EQ(STATUS_BAD_VALUE, AParcel_writeStatusHeader(in, status));
175 AStatus_delete(status);
176
177 return STATUS_UNKNOWN_ERROR;
178 }));
179
180 AIBinder_decStrong(binder);
181 }
182
TEST_F(NdkBinderTest_AParcel,WhatGoesInMustComeOut)183 TEST_F(NdkBinderTest_AParcel, WhatGoesInMustComeOut) {
184 ExpectInOut<int32_t, AParcel_writeInt32, AParcel_readInt32>(
185 {-7, -1, 0, 1, 45});
186 ExpectInOut<uint32_t, AParcel_writeUint32, AParcel_readUint32>(
187 {0, 1, 2, 100});
188 ExpectInOut<int64_t, AParcel_writeInt64, AParcel_readInt64>(
189 {-7, -1, 0, 1, 45});
190 ExpectInOut<uint64_t, AParcel_writeUint64, AParcel_readUint64>(
191 {0, 1, 2, 100});
192 ExpectInOut<float, AParcel_writeFloat, AParcel_readFloat>(
193 {-1.0f, 0.0f, 1.0f, 0.24975586f, 0.3f});
194 ExpectInOut<double, AParcel_writeDouble, AParcel_readDouble>(
195 {-1.0, 0.0, 1.0, 0.24975586, 0.3});
196
197 ExpectInOut<bool, AParcel_writeBool, AParcel_readBool>({true, false});
198 ExpectInOut<char16_t, AParcel_writeChar, AParcel_readChar>(
199 {L'\0', L'S', L'@', L'\n'});
200 ExpectInOut<int8_t, AParcel_writeByte, AParcel_readByte>({-7, -1, 0, 1, 45});
201 }
202
TEST_F(NdkBinderTest_AParcel,ExtremeValues)203 TEST_F(NdkBinderTest_AParcel, ExtremeValues) {
204 ExpectInOutMinMax<int32_t, AParcel_writeInt32, AParcel_readInt32>();
205 ExpectInOutMinMax<uint32_t, AParcel_writeUint32, AParcel_readUint32>();
206 ExpectInOutMinMax<int64_t, AParcel_writeInt64, AParcel_readInt64>();
207 ExpectInOutMinMax<uint64_t, AParcel_writeUint64, AParcel_readUint64>();
208 ExpectInOutMinMax<float, AParcel_writeFloat, AParcel_readFloat>();
209 ExpectInOutMinMax<double, AParcel_writeDouble, AParcel_readDouble>();
210 ExpectInOutMinMax<bool, AParcel_writeBool, AParcel_readBool>();
211 ExpectInOutMinMax<char16_t, AParcel_writeChar, AParcel_readChar>();
212 ExpectInOutMinMax<int8_t, AParcel_writeByte, AParcel_readByte>();
213 }
214
TEST_F(NdkBinderTest_AParcel,NonNullTerminatedString)215 TEST_F(NdkBinderTest_AParcel, NonNullTerminatedString) {
216 // This is a helper to write a vector of strings which are not
217 // null-terminated. It has infinite length, and every element is the same
218 // value (element.substr(0, elementLen)). However, when it is written, no
219 // copies of element are made to produce a null-terminated string.
220 struct PartialStringCycle {
221 // every element of the vector is a prefix of this string
222 const std::string& element;
223 // this is the number of characters of the string to write, < element.size()
224 int32_t elementLen;
225
226 binder_status_t writeToParcel(AParcel* p, size_t length) const {
227 return AParcel_writeStringArray(p, static_cast<const void*>(this), length,
228 ElementGetter);
229 }
230
231 private:
232 static const char* ElementGetter(const void* vectorData, size_t /*index*/, int32_t* outLength) {
233 const PartialStringCycle* vector =
234 static_cast<const PartialStringCycle*>(vectorData);
235
236 *outLength = vector->elementLen;
237 return vector->element.c_str();
238 }
239 };
240
241 const std::string kTestcase = "aoeuhtns";
242
243 for (size_t i = 0; i < kTestcase.size(); i++) {
244 const std::string expectedString = kTestcase.substr(0, i);
245 const std::vector<std::string> expectedVector = {expectedString,
246 expectedString};
247
248 const PartialStringCycle writeVector{.element = kTestcase,
249 .elementLen = static_cast<int32_t>(i)};
250
251 AIBinder* binder = SampleData::newBinder(
252 [&](transaction_code_t, const AParcel* in, AParcel* /*out*/) {
253 std::string readString;
254 EXPECT_OK(::ndk::AParcel_readString(in, &readString));
255 EXPECT_EQ(expectedString, readString);
256
257 std::vector<std::string> readVector;
258 EXPECT_OK(::ndk::AParcel_readVector(in, &readVector));
259 EXPECT_EQ(expectedVector, readVector);
260
261 return STATUS_OK;
262 },
263 ExpectLifetimeTransactions(1));
264
265 EXPECT_OK(SampleData::transact(
266 binder, kCode,
267 [&](AParcel* in) {
268 EXPECT_OK(AParcel_writeString(in, kTestcase.c_str(), i));
269 EXPECT_OK(writeVector.writeToParcel(in, expectedVector.size()));
270 return STATUS_OK;
271 },
272 ReadNothingFromParcel));
273
274 AIBinder_decStrong(binder);
275 }
276 }
277
TEST_F(NdkBinderTest_AParcel,CantReadFromEmptyParcel)278 TEST_F(NdkBinderTest_AParcel, CantReadFromEmptyParcel) {
279 AIBinder* binder = SampleData::newBinder(TransactionsReturn(STATUS_OK),
280 ExpectLifetimeTransactions(1));
281
282 EXPECT_OK(SampleData::transact(
283 binder, kCode, WriteNothingToParcel, [&](const AParcel* out) {
284 bool readTarget = false;
285 EXPECT_EQ(STATUS_NOT_ENOUGH_DATA, AParcel_readBool(out, &readTarget));
286 EXPECT_FALSE(readTarget);
287 return STATUS_OK;
288 }));
289 AIBinder_decStrong(binder);
290 }
291
TEST_F(NdkBinderTest_AParcel,ReturnParcelPosition)292 TEST_F(NdkBinderTest_AParcel, ReturnParcelPosition) {
293 AIBinder* binder = SampleData::newBinder(
294 [&](transaction_code_t, const AParcel* /*in*/, AParcel* out) {
295 size_t position = AParcel_getDataPosition(out);
296 EXPECT_EQ(position, AParcel_getDataPosition(out));
297 EXPECT_OK(AParcel_setDataPosition(out, position));
298 EXPECT_EQ(position, AParcel_getDataPosition(out));
299
300 return STATUS_OK;
301 },
302 ExpectLifetimeTransactions(1));
303
304 EXPECT_OK(SampleData::transact(binder, kCode, WriteNothingToParcel,
305 ReadNothingFromParcel));
306
307 AIBinder_decStrong(binder);
308 }
309
TEST_F(NdkBinderTest_AParcel,TooLargePosition)310 TEST_F(NdkBinderTest_AParcel, TooLargePosition) {
311 AIBinder* binder = SampleData::newBinder(
312 [&](transaction_code_t, const AParcel* /*in*/, AParcel* out) {
313 EXPECT_OK(AParcel_setDataPosition(out, 0));
314 EXPECT_OK(AParcel_setDataPosition(out, INT32_MAX));
315 EXPECT_EQ(STATUS_BAD_VALUE, AParcel_setDataPosition(out, -1));
316 EXPECT_EQ(STATUS_BAD_VALUE, AParcel_setDataPosition(out, -2));
317 return STATUS_OK;
318 },
319 ExpectLifetimeTransactions(1));
320
321 EXPECT_OK(SampleData::transact(binder, kCode, WriteNothingToParcel,
322 ReadNothingFromParcel));
323
324 AIBinder_decStrong(binder);
325 }
326
TEST_F(NdkBinderTest_AParcel,RewritePositions)327 TEST_F(NdkBinderTest_AParcel, RewritePositions) {
328 const std::string kTestString1 = "asdf";
329 const std::string kTestString2 = "aoeu";
330
331 // v-- position v-- postPosition
332 // | delta | "asdf" | "aoeu" |
333 // ^-- prePosition
334 //
335 // uint32_t delta = postPosition - prePosition
336
337 AIBinder* binder = SampleData::newBinder(
338 [&](transaction_code_t, const AParcel* in, AParcel* /*out*/) {
339 uint32_t delta;
340 EXPECT_OK(AParcel_readUint32(in, &delta));
341 size_t prePosition = AParcel_getDataPosition(in);
342 size_t postPosition = prePosition + delta;
343
344 std::string readString;
345
346 EXPECT_OK(AParcel_setDataPosition(in, postPosition));
347 EXPECT_OK(::ndk::AParcel_readString(in, &readString));
348 EXPECT_EQ(kTestString2, readString);
349
350 EXPECT_OK(AParcel_setDataPosition(in, prePosition));
351 EXPECT_OK(::ndk::AParcel_readString(in, &readString));
352 EXPECT_EQ(kTestString1, readString);
353
354 EXPECT_EQ(postPosition, AParcel_getDataPosition(in));
355
356 return STATUS_OK;
357 },
358 ExpectLifetimeTransactions(1));
359
360 EXPECT_OK(SampleData::transact(
361 binder, kCode,
362 [&](AParcel* in) {
363 size_t position = AParcel_getDataPosition(in);
364 EXPECT_OK(AParcel_writeUint32(in, 0)); // placeholder
365 size_t prePosition = AParcel_getDataPosition(in);
366 EXPECT_OK(::ndk::AParcel_writeString(in, kTestString1));
367 size_t postPosition = AParcel_getDataPosition(in);
368 EXPECT_OK(::ndk::AParcel_writeString(in, kTestString2));
369
370 size_t delta = postPosition - prePosition;
371 EXPECT_OK(AParcel_setDataPosition(in, position));
372 EXPECT_OK(AParcel_writeUint32(in, static_cast<uint32_t>(delta)));
373
374 return STATUS_OK;
375 },
376 ReadNothingFromParcel));
377
378 AIBinder_decStrong(binder);
379 }
380
TEST_F(NdkBinderTest_AParcel,CreateParcelTest)381 TEST_F(NdkBinderTest_AParcel, CreateParcelTest) {
382 AParcel* p = AParcel_create();
383 EXPECT_TRUE(p);
384 EXPECT_EQ(0, AParcel_getDataSize(p));
385 EXPECT_EQ(0, AParcel_getDataPosition(p));
386 AParcel_delete(p);
387 }
388
TEST_F(NdkBinderTest_AParcel,AppendFromTest)389 TEST_F(NdkBinderTest_AParcel, AppendFromTest) {
390 AParcel* p1 = AParcel_create();
391 AParcel* p2 = AParcel_create();
392
393 AParcel_writeInt32(p1, 42);
394
395 AParcel_appendFrom(p1, p2, 0, AParcel_getDataSize(p1));
396 EXPECT_EQ(AParcel_getDataSize(p1), AParcel_getDataSize(p1));
397
398 int32_t actual = 0;
399 AParcel_setDataPosition(p2, 0);
400 AParcel_readInt32(p2, &actual);
401
402 EXPECT_EQ(42, actual);
403
404 AParcel_delete(p1);
405 AParcel_delete(p2);
406 }
407
TEST_F(NdkBinderTest_AParcel,ResetTest)408 TEST_F(NdkBinderTest_AParcel, ResetTest) {
409 AParcel* p = AParcel_create();
410
411 AParcel_writeInt32(p, 42);
412 AParcel_reset(p);
413 EXPECT_EQ(0, AParcel_getDataSize(p));
414 EXPECT_EQ(0, AParcel_getDataPosition(p));
415
416 AParcel_writeInt32(p, 24);
417 AParcel_setDataPosition(p, 0);
418 int actual = 0;
419 AParcel_readInt32(p, &actual);
420
421 EXPECT_EQ(24, actual);
422 EXPECT_EQ(AParcel_getDataSize(p), AParcel_getDataPosition(p));
423
424 AParcel_delete(p);
425 }
426
TEST_F(NdkBinderTest_AParcel,GetDataSizeTest)427 TEST_F(NdkBinderTest_AParcel, GetDataSizeTest) {
428 AParcel* p = AParcel_create();
429
430 AParcel_writeInt32(p, 42);
431 EXPECT_EQ(AParcel_getDataSize(p), AParcel_getDataPosition(p));
432
433 AParcel_delete(p);
434 }
435
TEST_F(NdkBinderTest_AParcel,MarshalUnmarshalTest)436 TEST_F(NdkBinderTest_AParcel, MarshalUnmarshalTest) {
437 AParcel* p1 = AParcel_create();
438 AParcel* p2 = AParcel_create();
439
440 AParcel_writeInt32(p1, 42);
441 int dataSize = AParcel_getDataSize(p1);
442 uint8_t* data = new uint8_t[dataSize];
443 EXPECT_OK(AParcel_marshal(p1, data, 0, dataSize));
444
445 EXPECT_OK(AParcel_unmarshal(p2, data, dataSize));
446
447 int32_t actual = 0;
448 AParcel_setDataPosition(p2, 0);
449 AParcel_readInt32(p2, &actual);
450
451 EXPECT_EQ(42, actual);
452
453 AParcel_delete(p1);
454 AParcel_delete(p2);
455 delete[] data;
456 }
457
TEST_F(NdkBinderTest_AParcel,MarshalParcelWithBinderTest)458 TEST_F(NdkBinderTest_AParcel, MarshalParcelWithBinderTest) {
459 AParcel* p = AParcel_create();
460
461 AIBinder* binder = SampleData::newBinder();
462 EXPECT_OK(AParcel_writeStrongBinder(p, binder));
463
464 int dataSize = AParcel_getDataSize(p);
465 uint8_t* data = new uint8_t[dataSize];
466 EXPECT_EQ(STATUS_INVALID_OPERATION, AParcel_marshal(p, data, 0, dataSize));
467
468 AIBinder_decStrong(binder);
469 AParcel_delete(p);
470 delete[] data;
471 }
472
TEST_F(NdkBinderTest_AParcel,MarshalParcelWithFdTest)473 TEST_F(NdkBinderTest_AParcel, MarshalParcelWithFdTest) {
474 AParcel* p = AParcel_create();
475
476 EXPECT_OK(AParcel_writeParcelFileDescriptor(p, 1));
477
478 int dataSize = AParcel_getDataSize(p);
479 uint8_t* data = new uint8_t[dataSize];
480 EXPECT_EQ(STATUS_INVALID_OPERATION, AParcel_marshal(p, data, 0, dataSize));
481
482 AParcel_delete(p);
483 delete[] data;
484 }
485
TEST_F(NdkBinderTest_AParcel,MarshalParcelBufferTooSmall)486 TEST_F(NdkBinderTest_AParcel, MarshalParcelBufferTooSmall) {
487 AParcel* p = AParcel_create();
488
489 AParcel_writeInt32(p, 42);
490 int dataSize = AParcel_getDataSize(p);
491 uint8_t* data = new uint8_t[dataSize];
492 EXPECT_EQ(STATUS_BAD_VALUE, AParcel_marshal(p, data, 1, dataSize));
493
494 AParcel_delete(p);
495 delete[] data;
496 }
497