blob: ec7c7d8c885ddf2b177444ca2ed27a4285dd4b86 [file] [log] [blame]
Steven Moreland2e87adc2018-08-20 19:47:00 -07001/*
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
17#include <android/binder_parcel.h>
John Reck79fb24b2020-02-14 13:56:19 -080018#include <android/binder_parcel_platform.h>
Steven Moreland4d5ad492018-09-13 12:49:16 -070019#include "parcel_internal.h"
Steven Moreland2e87adc2018-08-20 19:47:00 -070020
Steven Moreland4d5ad492018-09-13 12:49:16 -070021#include "ibinder_internal.h"
Steven Moreland5d62e442018-09-13 15:01:02 -070022#include "status_internal.h"
Steven Moreland2e87adc2018-08-20 19:47:00 -070023
Steven Moreland7b06f592018-10-03 19:25:32 -070024#include <limits>
25
26#include <android-base/logging.h>
Steven Moreland063f2362018-10-18 12:49:11 -070027#include <android-base/unique_fd.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070028#include <binder/Parcel.h>
Steven Moreland063f2362018-10-18 12:49:11 -070029#include <binder/ParcelFileDescriptor.h>
Steven Moreland7b06f592018-10-03 19:25:32 -070030#include <utils/Unicode.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070031
32using ::android::IBinder;
33using ::android::Parcel;
34using ::android::sp;
Steven Moreland5d62e442018-09-13 15:01:02 -070035using ::android::status_t;
Steven Moreland063f2362018-10-18 12:49:11 -070036using ::android::base::unique_fd;
37using ::android::os::ParcelFileDescriptor;
Steven Moreland2e87adc2018-08-20 19:47:00 -070038
Steven Morelanda8845662018-10-12 11:53:03 -070039template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -080040using ContiguousArrayAllocator = bool (*)(void* arrayData, int32_t length, T** outBuffer);
Steven Moreland71872f82018-10-29 11:46:56 -070041
42template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -080043using ArrayAllocator = bool (*)(void* arrayData, int32_t length);
Steven Morelanda8845662018-10-12 11:53:03 -070044template <typename T>
45using ArrayGetter = T (*)(const void* arrayData, size_t index);
46template <typename T>
47using ArraySetter = void (*)(void* arrayData, size_t index, T value);
48
Steven Moreland01ebcf72018-11-15 15:06:26 -080049binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray, int32_t length) {
50 // only -1 can be used to represent a null array
51 if (length < -1) return STATUS_BAD_VALUE;
52
53 if (!isNullArray && length < 0) {
Steven Moreland2c20bbf2019-10-30 15:18:58 -070054 LOG(ERROR) << __func__ << ": non-null array but length is " << length;
Steven Moreland01ebcf72018-11-15 15:06:26 -080055 return STATUS_BAD_VALUE;
56 }
57 if (isNullArray && length > 0) {
58 LOG(ERROR) << __func__ << ": null buffer cannot be for size " << length << " array.";
59 return STATUS_BAD_VALUE;
60 }
Steven Morelanda8845662018-10-12 11:53:03 -070061
62 Parcel* rawParcel = parcel->get();
63
64 status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
65 if (status != STATUS_OK) return PruneStatusT(status);
66
Steven Moreland01ebcf72018-11-15 15:06:26 -080067 return STATUS_OK;
68}
69
70template <typename T>
71binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
72 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
73 if (status != STATUS_OK) return status;
74 if (length <= 0) return STATUS_OK;
75
Steven Morelanda8845662018-10-12 11:53:03 -070076 int32_t size = 0;
77 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
78
Steven Moreland01ebcf72018-11-15 15:06:26 -080079 void* const data = parcel->get()->writeInplace(size);
Steven Morelanda8845662018-10-12 11:53:03 -070080 if (data == nullptr) return STATUS_NO_MEMORY;
81
82 memcpy(data, array, size);
83
84 return STATUS_OK;
85}
86
87// Each element in a char16_t array is converted to an int32_t (not packed).
88template <>
Steven Moreland01ebcf72018-11-15 15:06:26 -080089binder_status_t WriteArray<char16_t>(AParcel* parcel, const char16_t* array, int32_t length) {
90 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
91 if (status != STATUS_OK) return status;
92 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -070093
94 int32_t size = 0;
95 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
96
Steven Moreland01ebcf72018-11-15 15:06:26 -080097 Parcel* rawParcel = parcel->get();
98
Steven Morelanda8845662018-10-12 11:53:03 -070099 for (int32_t i = 0; i < length; i++) {
100 status = rawParcel->writeChar(array[i]);
101
102 if (status != STATUS_OK) return PruneStatusT(status);
103 }
104
105 return STATUS_OK;
106}
107
108template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -0700109binder_status_t ReadArray(const AParcel* parcel, void* arrayData,
110 ContiguousArrayAllocator<T> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -0700111 const Parcel* rawParcel = parcel->get();
112
113 int32_t length;
114 status_t status = rawParcel->readInt32(&length);
115
116 if (status != STATUS_OK) return PruneStatusT(status);
Steven Moreland01ebcf72018-11-15 15:06:26 -0800117 if (length < -1) return STATUS_BAD_VALUE;
Steven Morelanda8845662018-10-12 11:53:03 -0700118
Steven Moreland01ebcf72018-11-15 15:06:26 -0800119 T* array;
120 if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
121
122 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700123 if (array == nullptr) return STATUS_NO_MEMORY;
124
125 int32_t size = 0;
126 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
127
128 const void* data = rawParcel->readInplace(size);
129 if (data == nullptr) return STATUS_NO_MEMORY;
130
131 memcpy(array, data, size);
132
133 return STATUS_OK;
134}
135
136// Each element in a char16_t array is converted to an int32_t (not packed)
137template <>
Steven Moreland71872f82018-10-29 11:46:56 -0700138binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
139 ContiguousArrayAllocator<char16_t> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -0700140 const Parcel* rawParcel = parcel->get();
141
142 int32_t length;
143 status_t status = rawParcel->readInt32(&length);
144
145 if (status != STATUS_OK) return PruneStatusT(status);
Steven Moreland01ebcf72018-11-15 15:06:26 -0800146 if (length < -1) return STATUS_BAD_VALUE;
Steven Morelanda8845662018-10-12 11:53:03 -0700147
Steven Moreland01ebcf72018-11-15 15:06:26 -0800148 char16_t* array;
149 if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
150
151 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700152 if (array == nullptr) return STATUS_NO_MEMORY;
153
154 int32_t size = 0;
155 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
156
157 for (int32_t i = 0; i < length; i++) {
158 status = rawParcel->readChar(array + i);
159
160 if (status != STATUS_OK) return PruneStatusT(status);
161 }
162
163 return STATUS_OK;
164}
165
166template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -0800167binder_status_t WriteArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland16e1eae2018-11-01 09:51:53 -0700168 ArrayGetter<T> getter, status_t (Parcel::*write)(T)) {
Steven Moreland01ebcf72018-11-15 15:06:26 -0800169 // we have no clue if arrayData represents a null object or not, we can only infer from length
170 bool arrayIsNull = length < 0;
171 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
172 if (status != STATUS_OK) return status;
173 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700174
175 Parcel* rawParcel = parcel->get();
176
Steven Moreland763dc4c2018-12-12 11:30:06 -0800177 for (int32_t i = 0; i < length; i++) {
Steven Morelanda8845662018-10-12 11:53:03 -0700178 status = (rawParcel->*write)(getter(arrayData, i));
179
180 if (status != STATUS_OK) return PruneStatusT(status);
181 }
182
183 return STATUS_OK;
184}
185
186template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -0700187binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator<T> allocator,
188 ArraySetter<T> setter, status_t (Parcel::*read)(T*) const) {
Steven Morelanda8845662018-10-12 11:53:03 -0700189 const Parcel* rawParcel = parcel->get();
190
191 int32_t length;
192 status_t status = rawParcel->readInt32(&length);
193
194 if (status != STATUS_OK) return PruneStatusT(status);
Steven Moreland01ebcf72018-11-15 15:06:26 -0800195 if (length < -1) return STATUS_BAD_VALUE;
Steven Morelanda8845662018-10-12 11:53:03 -0700196
Steven Moreland71872f82018-10-29 11:46:56 -0700197 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
Steven Morelanda8845662018-10-12 11:53:03 -0700198
Steven Moreland01ebcf72018-11-15 15:06:26 -0800199 if (length <= 0) return STATUS_OK;
200
Steven Moreland763dc4c2018-12-12 11:30:06 -0800201 for (int32_t i = 0; i < length; i++) {
Steven Morelanda8845662018-10-12 11:53:03 -0700202 T readTarget;
203 status = (rawParcel->*read)(&readTarget);
204 if (status != STATUS_OK) return PruneStatusT(status);
205
Steven Moreland71872f82018-10-29 11:46:56 -0700206 setter(arrayData, i, readTarget);
Steven Morelanda8845662018-10-12 11:53:03 -0700207 }
208
209 return STATUS_OK;
210}
211
Steven Moreland9b80e282018-09-19 13:57:23 -0700212void AParcel_delete(AParcel* parcel) {
213 delete parcel;
Steven Morelandcaa776c2018-09-04 13:48:11 -0700214}
215
Steven Morelandf32d1b02018-11-27 12:44:10 -0800216binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
217 if (position < 0) {
218 return STATUS_BAD_VALUE;
219 }
220
221 parcel->get()->setDataPosition(position);
222 return STATUS_OK;
223}
224
225int32_t AParcel_getDataPosition(const AParcel* parcel) {
226 return parcel->get()->dataPosition();
227}
228
Steven Morelandf183fdd2020-10-27 00:12:12 +0000229void AParcel_markSensitive(const AParcel* parcel) {
230 return parcel->get()->markSensitive();
231}
232
Steven Moreland2e87adc2018-08-20 19:47:00 -0700233binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
Steven Morelandc0e46d32018-09-12 15:40:49 -0700234 sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700235 return parcel->get()->writeStrongBinder(writeBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700236}
237binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
238 sp<IBinder> readBinder = nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700239 status_t status = parcel->get()->readNullableStrongBinder(&readBinder);
Steven Moreland5d62e442018-09-13 15:01:02 -0700240 if (status != STATUS_OK) {
241 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700242 }
Steven Moreland94968952018-09-05 14:42:59 -0700243 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
Steven Moreland71cddc32018-08-30 23:39:22 -0700244 AIBinder_incStrong(ret.get());
245 *binder = ret.get();
Steven Moreland5d62e442018-09-13 15:01:02 -0700246 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700247}
Steven Moreland063f2362018-10-18 12:49:11 -0700248
249binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
Steven Moreland4ce59c72018-11-16 15:21:15 -0800250 if (fd < 0) {
251 if (fd != -1) {
252 return STATUS_UNKNOWN_ERROR;
253 }
Steven Moreland073c9c12020-02-19 17:02:08 -0800254 return PruneStatusT(parcel->get()->writeInt32(0)); // null
Steven Moreland4ce59c72018-11-16 15:21:15 -0800255 }
Steven Moreland073c9c12020-02-19 17:02:08 -0800256 status_t status = parcel->get()->writeInt32(1); // not-null
257 if (status != STATUS_OK) return PruneStatusT(status);
Steven Moreland4ce59c72018-11-16 15:21:15 -0800258
Steven Moreland073c9c12020-02-19 17:02:08 -0800259 status = parcel->get()->writeDupParcelFileDescriptor(fd);
Steven Moreland063f2362018-10-18 12:49:11 -0700260 return PruneStatusT(status);
261}
262
263binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
Jooyung Han4d9f91a2020-11-18 13:24:16 +0900264 std::optional<ParcelFileDescriptor> parcelFd;
Steven Moreland4ce59c72018-11-16 15:21:15 -0800265
Steven Moreland063f2362018-10-18 12:49:11 -0700266 status_t status = parcel->get()->readParcelable(&parcelFd);
267 if (status != STATUS_OK) return PruneStatusT(status);
268
Steven Moreland4ce59c72018-11-16 15:21:15 -0800269 if (parcelFd) {
270 *fd = parcelFd->release().release();
271 } else {
272 *fd = -1;
273 }
274
Steven Moreland063f2362018-10-18 12:49:11 -0700275 return STATUS_OK;
276}
277
Steven Moreland9a51db82018-09-14 10:59:35 -0700278binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
Steven Moreland85c138a2020-09-22 22:00:52 +0000279 return PruneStatusT(status->get().writeToParcel(parcel->get()));
Steven Moreland9a51db82018-09-14 10:59:35 -0700280}
281binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
282 ::android::binder::Status bstatus;
283 binder_status_t ret = PruneStatusT(bstatus.readFromParcel(*parcel->get()));
Steven Morelandc1a11b82018-10-29 18:47:23 -0700284 if (ret == STATUS_OK) {
Steven Moreland9a51db82018-09-14 10:59:35 -0700285 *status = new AStatus(std::move(bstatus));
286 }
Steven Morelandc1a11b82018-10-29 18:47:23 -0700287 return PruneStatusT(ret);
Steven Moreland9a51db82018-09-14 10:59:35 -0700288}
Steven Moreland2e87adc2018-08-20 19:47:00 -0700289
Steven Morelandb4e14612018-11-14 17:25:45 -0800290binder_status_t AParcel_writeString(AParcel* parcel, const char* string, int32_t length) {
291 if (string == nullptr) {
292 if (length != -1) {
293 LOG(WARNING) << __func__ << ": null string must be used with length == -1.";
294 return STATUS_BAD_VALUE;
295 }
Steven Moreland7b06f592018-10-03 19:25:32 -0700296
Steven Morelandb4e14612018-11-14 17:25:45 -0800297 status_t err = parcel->get()->writeInt32(-1);
298 return PruneStatusT(err);
299 }
300
301 if (length < 0) {
302 LOG(WARNING) << __func__ << ": Negative string length: " << length;
303 return STATUS_BAD_VALUE;
304 }
305
306 const uint8_t* str8 = (uint8_t*)string;
Steven Moreland7b06f592018-10-03 19:25:32 -0700307 const ssize_t len16 = utf8_to_utf16_length(str8, length);
308
309 if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
310 LOG(WARNING) << __func__ << ": Invalid string length: " << len16;
311 return STATUS_BAD_VALUE;
312 }
313
314 status_t err = parcel->get()->writeInt32(len16);
315 if (err) {
316 return PruneStatusT(err);
317 }
318
319 void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
320 if (str16 == nullptr) {
321 return STATUS_NO_MEMORY;
322 }
323
324 utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
325
326 return STATUS_OK;
327}
328
Steven Moreland07fb9c92018-11-01 17:14:29 -0700329binder_status_t AParcel_readString(const AParcel* parcel, void* stringData,
330 AParcel_stringAllocator allocator) {
Steven Moreland7b06f592018-10-03 19:25:32 -0700331 size_t len16;
332 const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
333
334 if (str16 == nullptr) {
Steven Morelandb4e14612018-11-14 17:25:45 -0800335 if (allocator(stringData, -1, nullptr)) {
336 return STATUS_OK;
337 }
338
Steven Moreland7b06f592018-10-03 19:25:32 -0700339 return STATUS_UNEXPECTED_NULL;
340 }
341
342 ssize_t len8;
343
344 if (len16 == 0) {
345 len8 = 1;
346 } else {
347 len8 = utf16_to_utf8_length(str16, len16) + 1;
348 }
349
Steven Moreland07fb9c92018-11-01 17:14:29 -0700350 if (len8 <= 0 || len8 > std::numeric_limits<int32_t>::max()) {
Steven Moreland7b06f592018-10-03 19:25:32 -0700351 LOG(WARNING) << __func__ << ": Invalid string length: " << len8;
352 return STATUS_BAD_VALUE;
353 }
354
Steven Morelandb4e14612018-11-14 17:25:45 -0800355 char* str8;
356 bool success = allocator(stringData, len8, &str8);
Steven Moreland7b06f592018-10-03 19:25:32 -0700357
Steven Morelandb4e14612018-11-14 17:25:45 -0800358 if (!success || str8 == nullptr) {
Steven Moreland71872f82018-10-29 11:46:56 -0700359 LOG(WARNING) << __func__ << ": AParcel_stringAllocator failed to allocate.";
Steven Moreland7b06f592018-10-03 19:25:32 -0700360 return STATUS_NO_MEMORY;
361 }
362
363 utf16_to_utf8(str16, len16, str8, len8);
364
365 return STATUS_OK;
366}
367
Steven Morelandb4e14612018-11-14 17:25:45 -0800368binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland07fb9c92018-11-01 17:14:29 -0700369 AParcel_stringArrayElementGetter getter) {
Steven Moreland01ebcf72018-11-15 15:06:26 -0800370 // we have no clue if arrayData represents a null object or not, we can only infer from length
371 bool arrayIsNull = length < 0;
372 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
373 if (status != STATUS_OK) return status;
374 if (length <= 0) return STATUS_OK;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700375
Steven Moreland763dc4c2018-12-12 11:30:06 -0800376 for (int32_t i = 0; i < length; i++) {
377 int32_t elementLength = 0;
Steven Morelande22a9942018-12-11 18:57:05 -0800378 const char* str = getter(arrayData, i, &elementLength);
379 if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700380
Steven Morelande22a9942018-12-11 18:57:05 -0800381 binder_status_t status = AParcel_writeString(parcel, str, elementLength);
Steven Moreland07fb9c92018-11-01 17:14:29 -0700382 if (status != STATUS_OK) return status;
383 }
384
385 return STATUS_OK;
386}
387
388// This implements AParcel_stringAllocator for a string using an array, index, and element
389// allocator.
390struct StringArrayElementAllocationAdapter {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700391 void* arrayData; // stringData from the NDK
Steven Moreland763dc4c2018-12-12 11:30:06 -0800392 int32_t index; // index into the string array
Steven Moreland07fb9c92018-11-01 17:14:29 -0700393 AParcel_stringArrayElementAllocator elementAllocator;
394
Steven Morelandb4e14612018-11-14 17:25:45 -0800395 static bool Allocator(void* stringData, int32_t length, char** buffer) {
Steven Moreland07fb9c92018-11-01 17:14:29 -0700396 StringArrayElementAllocationAdapter* adapter =
397 static_cast<StringArrayElementAllocationAdapter*>(stringData);
Steven Morelandb4e14612018-11-14 17:25:45 -0800398 return adapter->elementAllocator(adapter->arrayData, adapter->index, length, buffer);
Steven Moreland07fb9c92018-11-01 17:14:29 -0700399 }
400};
401
402binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
403 AParcel_stringArrayAllocator allocator,
404 AParcel_stringArrayElementAllocator elementAllocator) {
405 const Parcel* rawParcel = parcel->get();
406
407 int32_t length;
408 status_t status = rawParcel->readInt32(&length);
409
410 if (status != STATUS_OK) return PruneStatusT(status);
Steven Morelandb4e14612018-11-14 17:25:45 -0800411 if (length < -1) return STATUS_BAD_VALUE;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700412
413 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
414
Steven Morelandb4e14612018-11-14 17:25:45 -0800415 if (length == -1) return STATUS_OK; // null string array
416
Steven Moreland07fb9c92018-11-01 17:14:29 -0700417 StringArrayElementAllocationAdapter adapter{
418 .arrayData = arrayData,
419 .index = 0,
420 .elementAllocator = elementAllocator,
421 };
422
423 for (; adapter.index < length; adapter.index++) {
Steven Morelandb4e14612018-11-14 17:25:45 -0800424 binder_status_t status = AParcel_readString(parcel, static_cast<void*>(&adapter),
425 StringArrayElementAllocationAdapter::Allocator);
426
427 if (status != STATUS_OK) return status;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700428 }
429
430 return STATUS_OK;
431}
432
Steven Morelande22a9942018-12-11 18:57:05 -0800433binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
434 AParcel_writeParcelableElement elementWriter) {
435 // we have no clue if arrayData represents a null object or not, we can only infer from length
436 bool arrayIsNull = length < 0;
437 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
438 if (status != STATUS_OK) return status;
439 if (length <= 0) return STATUS_OK;
440
Steven Moreland763dc4c2018-12-12 11:30:06 -0800441 for (int32_t i = 0; i < length; i++) {
Steven Morelande22a9942018-12-11 18:57:05 -0800442 binder_status_t status = elementWriter(parcel, arrayData, i);
443 if (status != STATUS_OK) return status;
444 }
445
446 return STATUS_OK;
447}
448
449binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
450 AParcel_parcelableArrayAllocator allocator,
451 AParcel_readParcelableElement elementReader) {
452 const Parcel* rawParcel = parcel->get();
453
454 int32_t length;
455 status_t status = rawParcel->readInt32(&length);
456
457 if (status != STATUS_OK) return PruneStatusT(status);
458 if (length < -1) return STATUS_BAD_VALUE;
459
460 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
461
462 if (length == -1) return STATUS_OK; // null array
463
Steven Moreland763dc4c2018-12-12 11:30:06 -0800464 for (int32_t i = 0; i < length; i++) {
Steven Morelande22a9942018-12-11 18:57:05 -0800465 binder_status_t status = elementReader(parcel, arrayData, i);
466 if (status != STATUS_OK) return status;
467 }
468
469 return STATUS_OK;
470}
471
Steven Moreland2e87adc2018-08-20 19:47:00 -0700472// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
473// libbinder and this library.
474// @START
475binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700476 status_t status = parcel->get()->writeInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700477 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700478}
479
480binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700481 status_t status = parcel->get()->writeUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700482 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700483}
484
485binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700486 status_t status = parcel->get()->writeInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700487 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700488}
489
490binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700491 status_t status = parcel->get()->writeUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700492 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700493}
494
495binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700496 status_t status = parcel->get()->writeFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700497 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700498}
499
500binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700501 status_t status = parcel->get()->writeDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700502 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700503}
504
505binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700506 status_t status = parcel->get()->writeBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700507 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700508}
509
510binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700511 status_t status = parcel->get()->writeChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700512 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700513}
514
515binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700516 status_t status = parcel->get()->writeByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700517 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700518}
519
520binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700521 status_t status = parcel->get()->readInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700522 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700523}
524
525binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700526 status_t status = parcel->get()->readUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700527 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700528}
529
530binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700531 status_t status = parcel->get()->readInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700532 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700533}
534
535binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700536 status_t status = parcel->get()->readUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700537 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700538}
539
540binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700541 status_t status = parcel->get()->readFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700542 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700543}
544
545binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700546 status_t status = parcel->get()->readDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700547 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700548}
549
550binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700551 status_t status = parcel->get()->readBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700552 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700553}
554
555binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700556 status_t status = parcel->get()->readChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700557 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700558}
559
560binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700561 status_t status = parcel->get()->readByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700562 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700563}
564
Steven Moreland01ebcf72018-11-15 15:06:26 -0800565binder_status_t AParcel_writeInt32Array(AParcel* parcel, const int32_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700566 return WriteArray<int32_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700567}
568
Steven Morelande3d09582018-11-02 19:29:36 -0700569binder_status_t AParcel_writeUint32Array(AParcel* parcel, const uint32_t* arrayData,
Steven Moreland01ebcf72018-11-15 15:06:26 -0800570 int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700571 return WriteArray<uint32_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700572}
573
Steven Moreland01ebcf72018-11-15 15:06:26 -0800574binder_status_t AParcel_writeInt64Array(AParcel* parcel, const int64_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700575 return WriteArray<int64_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700576}
577
Steven Morelande3d09582018-11-02 19:29:36 -0700578binder_status_t AParcel_writeUint64Array(AParcel* parcel, const uint64_t* arrayData,
Steven Moreland01ebcf72018-11-15 15:06:26 -0800579 int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700580 return WriteArray<uint64_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700581}
582
Steven Moreland01ebcf72018-11-15 15:06:26 -0800583binder_status_t AParcel_writeFloatArray(AParcel* parcel, const float* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700584 return WriteArray<float>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700585}
586
Steven Moreland01ebcf72018-11-15 15:06:26 -0800587binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700588 return WriteArray<double>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700589}
590
Steven Moreland01ebcf72018-11-15 15:06:26 -0800591binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland16e1eae2018-11-01 09:51:53 -0700592 AParcel_boolArrayGetter getter) {
593 return WriteArray<bool>(parcel, arrayData, length, getter, &Parcel::writeBool);
Steven Morelanda8845662018-10-12 11:53:03 -0700594}
595
Steven Moreland01ebcf72018-11-15 15:06:26 -0800596binder_status_t AParcel_writeCharArray(AParcel* parcel, const char16_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700597 return WriteArray<char16_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700598}
599
Steven Moreland01ebcf72018-11-15 15:06:26 -0800600binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700601 return WriteArray<int8_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700602}
603
Steven Moreland71872f82018-10-29 11:46:56 -0700604binder_status_t AParcel_readInt32Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700605 AParcel_int32ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700606 return ReadArray<int32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700607}
608
Steven Moreland71872f82018-10-29 11:46:56 -0700609binder_status_t AParcel_readUint32Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700610 AParcel_uint32ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700611 return ReadArray<uint32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700612}
613
Steven Moreland71872f82018-10-29 11:46:56 -0700614binder_status_t AParcel_readInt64Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700615 AParcel_int64ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700616 return ReadArray<int64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700617}
618
Steven Moreland71872f82018-10-29 11:46:56 -0700619binder_status_t AParcel_readUint64Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700620 AParcel_uint64ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700621 return ReadArray<uint64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700622}
623
Steven Moreland71872f82018-10-29 11:46:56 -0700624binder_status_t AParcel_readFloatArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700625 AParcel_floatArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700626 return ReadArray<float>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700627}
628
Steven Moreland71872f82018-10-29 11:46:56 -0700629binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700630 AParcel_doubleArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700631 return ReadArray<double>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700632}
633
Steven Moreland71872f82018-10-29 11:46:56 -0700634binder_status_t AParcel_readBoolArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700635 AParcel_boolArrayAllocator allocator,
Steven Morelanda8845662018-10-12 11:53:03 -0700636 AParcel_boolArraySetter setter) {
Steven Moreland71872f82018-10-29 11:46:56 -0700637 return ReadArray<bool>(parcel, arrayData, allocator, setter, &Parcel::readBool);
Steven Morelanda8845662018-10-12 11:53:03 -0700638}
639
Steven Moreland71872f82018-10-29 11:46:56 -0700640binder_status_t AParcel_readCharArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700641 AParcel_charArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700642 return ReadArray<char16_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700643}
644
Steven Moreland71872f82018-10-29 11:46:56 -0700645binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700646 AParcel_byteArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700647 return ReadArray<int8_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700648}
649
John Reck79fb24b2020-02-14 13:56:19 -0800650bool AParcel_getAllowFds(const AParcel* parcel) {
651 return parcel->get()->allowFds();
652}
653
Jeongik Cha62240b92020-10-14 00:06:01 +0900654binder_status_t AParcel_reset(AParcel* parcel) {
655 parcel->get()->freeData();
656 return STATUS_OK;
657}
658
659int32_t AParcel_getDataSize(const AParcel* parcel) {
660 return parcel->get()->dataSize();
661}
662
663binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) {
664 status_t status = to->get()->appendFrom(from->get(), start, size);
665 return PruneStatusT(status);
666}
667
668AParcel* AParcel_create() {
669 return new AParcel(nullptr);
670}
671
Steven Moreland2e87adc2018-08-20 19:47:00 -0700672// @END