1 /*
2 * Copyright (C) 2005 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 #ifndef ANDROID_PARCEL_H
18 #define ANDROID_PARCEL_H
19
20 #include <map> // for legacy reasons
21 #include <string>
22 #include <type_traits>
23 #include <vector>
24
25 #include <android-base/unique_fd.h>
26 #include <cutils/native_handle.h>
27 #include <utils/Errors.h>
28 #include <utils/RefBase.h>
29 #include <utils/String16.h>
30 #include <utils/Vector.h>
31 #include <utils/Flattenable.h>
32
33 #include <binder/IInterface.h>
34 #include <binder/Parcelable.h>
35
36 #ifdef BINDER_IPC_32BIT
37 typedef unsigned int binder_size_t;
38 #else
39 typedef unsigned long long binder_size_t;
40 #endif
41
42
43 // ---------------------------------------------------------------------------
44 namespace android {
45
46 template <typename T> class Flattenable;
47 template <typename T> class LightFlattenable;
48 struct flat_binder_object;
49 class IBinder;
50 class IPCThreadState;
51 class ProcessState;
52 class String8;
53 class TextOutput;
54
55 class Parcel {
56 friend class IPCThreadState;
57 public:
58 class ReadableBlob;
59 class WritableBlob;
60
61 Parcel();
62 ~Parcel();
63
64 const uint8_t* data() const;
65 size_t dataSize() const;
66 size_t dataAvail() const;
67 size_t dataPosition() const;
68 size_t dataCapacity() const;
69
70 status_t setDataSize(size_t size);
71 void setDataPosition(size_t pos) const;
72 status_t setDataCapacity(size_t size);
73
74 status_t setData(const uint8_t* buffer, size_t len);
75
76 status_t appendFrom(const Parcel *parcel,
77 size_t start, size_t len);
78
79 int compareData(const Parcel& other);
80
81 bool allowFds() const;
82 bool pushAllowFds(bool allowFds);
83 void restoreAllowFds(bool lastValue);
84
85 bool hasFileDescriptors() const;
86
87 // Writes the RPC header.
88 status_t writeInterfaceToken(const String16& interface);
89
90 // Parses the RPC header, returning true if the interface name
91 // in the header matches the expected interface from the caller.
92 //
93 // Additionally, enforceInterface does part of the work of
94 // propagating the StrictMode policy mask, populating the current
95 // IPCThreadState, which as an optimization may optionally be
96 // passed in.
97 bool enforceInterface(const String16& interface,
98 IPCThreadState* threadState = nullptr) const;
99 bool enforceInterface(const char16_t* interface,
100 size_t len,
101 IPCThreadState* threadState = nullptr) const;
102 bool checkInterface(IBinder*) const;
103
104 void freeData();
105
106 size_t objectsCount() const;
107
108 status_t errorCheck() const;
109 void setError(status_t err);
110
111 status_t write(const void* data, size_t len);
112 void* writeInplace(size_t len);
113 status_t writeUnpadded(const void* data, size_t len);
114 status_t writeInt32(int32_t val);
115 status_t writeUint32(uint32_t val);
116 status_t writeInt64(int64_t val);
117 status_t writeUint64(uint64_t val);
118 status_t writeFloat(float val);
119 status_t writeDouble(double val);
120 status_t writeCString(const char* str);
121 status_t writeString8(const String8& str);
122 status_t writeString8(const char* str, size_t len);
123 status_t writeString16(const String16& str);
124 status_t writeString16(const std::unique_ptr<String16>& str);
125 status_t writeString16(const char16_t* str, size_t len);
126 status_t writeStrongBinder(const sp<IBinder>& val);
127 status_t writeInt32Array(size_t len, const int32_t *val);
128 status_t writeByteArray(size_t len, const uint8_t *val);
129 status_t writeBool(bool val);
130 status_t writeChar(char16_t val);
131 status_t writeByte(int8_t val);
132
133 // Take a UTF8 encoded string, convert to UTF16, write it to the parcel.
134 status_t writeUtf8AsUtf16(const std::string& str);
135 status_t writeUtf8AsUtf16(const std::unique_ptr<std::string>& str);
136
137 status_t writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val);
138 status_t writeByteVector(const std::vector<int8_t>& val);
139 status_t writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val);
140 status_t writeByteVector(const std::vector<uint8_t>& val);
141 status_t writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val);
142 status_t writeInt32Vector(const std::vector<int32_t>& val);
143 status_t writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);
144 status_t writeInt64Vector(const std::vector<int64_t>& val);
145 status_t writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val);
146 status_t writeUint64Vector(const std::vector<uint64_t>& val);
147 status_t writeFloatVector(const std::unique_ptr<std::vector<float>>& val);
148 status_t writeFloatVector(const std::vector<float>& val);
149 status_t writeDoubleVector(const std::unique_ptr<std::vector<double>>& val);
150 status_t writeDoubleVector(const std::vector<double>& val);
151 status_t writeBoolVector(const std::unique_ptr<std::vector<bool>>& val);
152 status_t writeBoolVector(const std::vector<bool>& val);
153 status_t writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val);
154 status_t writeCharVector(const std::vector<char16_t>& val);
155 status_t writeString16Vector(
156 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val);
157 status_t writeString16Vector(const std::vector<String16>& val);
158 status_t writeUtf8VectorAsUtf16Vector(
159 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val);
160 status_t writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val);
161
162 status_t writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
163 status_t writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
164
165 // Write an Enum vector with underlying type int8_t.
166 // Does not use padding; each byte is contiguous.
167 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
168 status_t writeEnumVector(const std::vector<T>& val);
169 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
170 status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
171 // Write an Enum vector with underlying type != int8_t.
172 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
173 status_t writeEnumVector(const std::vector<T>& val);
174 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
175 status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
176
177 template<typename T>
178 status_t writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val);
179 template<typename T>
180 status_t writeParcelableVector(const std::shared_ptr<std::vector<std::unique_ptr<T>>>& val);
181 template<typename T>
182 status_t writeParcelableVector(const std::vector<T>& val);
183
184 template<typename T>
185 status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable);
186
187 status_t writeParcelable(const Parcelable& parcelable);
188
189 template<typename T>
190 status_t write(const Flattenable<T>& val);
191
192 template<typename T>
193 status_t write(const LightFlattenable<T>& val);
194
195 template<typename T>
196 status_t writeVectorSize(const std::vector<T>& val);
197 template<typename T>
198 status_t writeVectorSize(const std::unique_ptr<std::vector<T>>& val);
199
200 // Place a native_handle into the parcel (the native_handle's file-
201 // descriptors are dup'ed, so it is safe to delete the native_handle
202 // when this function returns).
203 // Doesn't take ownership of the native_handle.
204 status_t writeNativeHandle(const native_handle* handle);
205
206 // Place a file descriptor into the parcel. The given fd must remain
207 // valid for the lifetime of the parcel.
208 // The Parcel does not take ownership of the given fd unless you ask it to.
209 status_t writeFileDescriptor(int fd, bool takeOwnership = false);
210
211 // Place a file descriptor into the parcel. A dup of the fd is made, which
212 // will be closed once the parcel is destroyed.
213 status_t writeDupFileDescriptor(int fd);
214
215 // Place a Java "parcel file descriptor" into the parcel. The given fd must remain
216 // valid for the lifetime of the parcel.
217 // The Parcel does not take ownership of the given fd unless you ask it to.
218 status_t writeParcelFileDescriptor(int fd, bool takeOwnership = false);
219
220 // Place a Java "parcel file descriptor" into the parcel. A dup of the fd is made, which will
221 // be closed once the parcel is destroyed.
222 status_t writeDupParcelFileDescriptor(int fd);
223
224 // Place a file descriptor into the parcel. This will not affect the
225 // semantics of the smart file descriptor. A new descriptor will be
226 // created, and will be closed when the parcel is destroyed.
227 status_t writeUniqueFileDescriptor(
228 const base::unique_fd& fd);
229
230 // Place a vector of file desciptors into the parcel. Each descriptor is
231 // dup'd as in writeDupFileDescriptor
232 status_t writeUniqueFileDescriptorVector(
233 const std::unique_ptr<std::vector<base::unique_fd>>& val);
234 status_t writeUniqueFileDescriptorVector(
235 const std::vector<base::unique_fd>& val);
236
237 // Writes a blob to the parcel.
238 // If the blob is small, then it is stored in-place, otherwise it is
239 // transferred by way of an anonymous shared memory region. Prefer sending
240 // immutable blobs if possible since they may be subsequently transferred between
241 // processes without further copying whereas mutable blobs always need to be copied.
242 // The caller should call release() on the blob after writing its contents.
243 status_t writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob);
244
245 // Write an existing immutable blob file descriptor to the parcel.
246 // This allows the client to send the same blob to multiple processes
247 // as long as it keeps a dup of the blob file descriptor handy for later.
248 status_t writeDupImmutableBlobFileDescriptor(int fd);
249
250 status_t writeObject(const flat_binder_object& val, bool nullMetaData);
251
252 // Like Parcel.java's writeNoException(). Just writes a zero int32.
253 // Currently the native implementation doesn't do any of the StrictMode
254 // stack gathering and serialization that the Java implementation does.
255 status_t writeNoException();
256
257 status_t read(void* outData, size_t len) const;
258 const void* readInplace(size_t len) const;
259 int32_t readInt32() const;
260 status_t readInt32(int32_t *pArg) const;
261 uint32_t readUint32() const;
262 status_t readUint32(uint32_t *pArg) const;
263 int64_t readInt64() const;
264 status_t readInt64(int64_t *pArg) const;
265 uint64_t readUint64() const;
266 status_t readUint64(uint64_t *pArg) const;
267 float readFloat() const;
268 status_t readFloat(float *pArg) const;
269 double readDouble() const;
270 status_t readDouble(double *pArg) const;
271 intptr_t readIntPtr() const;
272 status_t readIntPtr(intptr_t *pArg) const;
273 bool readBool() const;
274 status_t readBool(bool *pArg) const;
275 char16_t readChar() const;
276 status_t readChar(char16_t *pArg) const;
277 int8_t readByte() const;
278 status_t readByte(int8_t *pArg) const;
279
280 // Read a UTF16 encoded string, convert to UTF8
281 status_t readUtf8FromUtf16(std::string* str) const;
282 status_t readUtf8FromUtf16(std::unique_ptr<std::string>* str) const;
283
284 const char* readCString() const;
285 String8 readString8() const;
286 status_t readString8(String8* pArg) const;
287 const char* readString8Inplace(size_t* outLen) const;
288 String16 readString16() const;
289 status_t readString16(String16* pArg) const;
290 status_t readString16(std::unique_ptr<String16>* pArg) const;
291 const char16_t* readString16Inplace(size_t* outLen) const;
292 sp<IBinder> readStrongBinder() const;
293 status_t readStrongBinder(sp<IBinder>* val) const;
294 status_t readNullableStrongBinder(sp<IBinder>* val) const;
295
296
297 // Read an Enum vector with underlying type int8_t.
298 // Does not use padding; each byte is contiguous.
299 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
300 status_t readEnumVector(std::vector<T>* val) const;
301 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
302 status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
303 // Read an Enum vector with underlying type != int8_t.
304 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
305 status_t readEnumVector(std::vector<T>* val) const;
306 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
307 status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
308
309 template<typename T>
310 status_t readParcelableVector(
311 std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const;
312 template<typename T>
313 status_t readParcelableVector(std::vector<T>* val) const;
314
315 status_t readParcelable(Parcelable* parcelable) const;
316
317 template<typename T>
318 status_t readParcelable(std::unique_ptr<T>* parcelable) const;
319
320 template<typename T>
321 status_t readStrongBinder(sp<T>* val) const;
322
323 template<typename T>
324 status_t readNullableStrongBinder(sp<T>* val) const;
325
326 status_t readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;
327 status_t readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
328
329 status_t readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const;
330 status_t readByteVector(std::vector<int8_t>* val) const;
331 status_t readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const;
332 status_t readByteVector(std::vector<uint8_t>* val) const;
333 status_t readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const;
334 status_t readInt32Vector(std::vector<int32_t>* val) const;
335 status_t readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;
336 status_t readInt64Vector(std::vector<int64_t>* val) const;
337 status_t readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const;
338 status_t readUint64Vector(std::vector<uint64_t>* val) const;
339 status_t readFloatVector(std::unique_ptr<std::vector<float>>* val) const;
340 status_t readFloatVector(std::vector<float>* val) const;
341 status_t readDoubleVector(std::unique_ptr<std::vector<double>>* val) const;
342 status_t readDoubleVector(std::vector<double>* val) const;
343 status_t readBoolVector(std::unique_ptr<std::vector<bool>>* val) const;
344 status_t readBoolVector(std::vector<bool>* val) const;
345 status_t readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const;
346 status_t readCharVector(std::vector<char16_t>* val) const;
347 status_t readString16Vector(
348 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;
349 status_t readString16Vector(std::vector<String16>* val) const;
350 status_t readUtf8VectorFromUtf16Vector(
351 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const;
352 status_t readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const;
353
354 template<typename T>
355 status_t read(Flattenable<T>& val) const;
356
357 template<typename T>
358 status_t read(LightFlattenable<T>& val) const;
359
360 template<typename T>
361 status_t resizeOutVector(std::vector<T>* val) const;
362 template<typename T>
363 status_t resizeOutVector(std::unique_ptr<std::vector<T>>* val) const;
364 template<typename T>
365 status_t reserveOutVector(std::vector<T>* val, size_t* size) const;
366 template<typename T>
367 status_t reserveOutVector(std::unique_ptr<std::vector<T>>* val,
368 size_t* size) const;
369
370 // Like Parcel.java's readExceptionCode(). Reads the first int32
371 // off of a Parcel's header, returning 0 or the negative error
372 // code on exceptions, but also deals with skipping over rich
373 // response headers. Callers should use this to read & parse the
374 // response headers rather than doing it by hand.
375 int32_t readExceptionCode() const;
376
377 // Retrieve native_handle from the parcel. This returns a copy of the
378 // parcel's native_handle (the caller takes ownership). The caller
379 // must free the native_handle with native_handle_close() and
380 // native_handle_delete().
381 native_handle* readNativeHandle() const;
382
383
384 // Retrieve a file descriptor from the parcel. This returns the raw fd
385 // in the parcel, which you do not own -- use dup() to get your own copy.
386 int readFileDescriptor() const;
387
388 // Retrieve a Java "parcel file descriptor" from the parcel. This returns the raw fd
389 // in the parcel, which you do not own -- use dup() to get your own copy.
390 int readParcelFileDescriptor() const;
391
392 // Retrieve a smart file descriptor from the parcel.
393 status_t readUniqueFileDescriptor(
394 base::unique_fd* val) const;
395
396 // Retrieve a Java "parcel file descriptor" from the parcel.
397 status_t readUniqueParcelFileDescriptor(base::unique_fd* val) const;
398
399
400 // Retrieve a vector of smart file descriptors from the parcel.
401 status_t readUniqueFileDescriptorVector(
402 std::unique_ptr<std::vector<base::unique_fd>>* val) const;
403 status_t readUniqueFileDescriptorVector(
404 std::vector<base::unique_fd>* val) const;
405
406 // Reads a blob from the parcel.
407 // The caller should call release() on the blob after reading its contents.
408 status_t readBlob(size_t len, ReadableBlob* outBlob) const;
409
410 const flat_binder_object* readObject(bool nullMetaData) const;
411
412 // Explicitly close all file descriptors in the parcel.
413 void closeFileDescriptors();
414
415 // Debugging: get metrics on current allocations.
416 static size_t getGlobalAllocSize();
417 static size_t getGlobalAllocCount();
418
419 bool replaceCallingWorkSourceUid(uid_t uid);
420 // Returns the work source provided by the caller. This can only be trusted for trusted calling
421 // uid.
422 uid_t readCallingWorkSourceUid() const;
423
424 private:
425 typedef void (*release_func)(Parcel* parcel,
426 const uint8_t* data, size_t dataSize,
427 const binder_size_t* objects, size_t objectsSize,
428 void* cookie);
429
430 uintptr_t ipcData() const;
431 size_t ipcDataSize() const;
432 uintptr_t ipcObjects() const;
433 size_t ipcObjectsCount() const;
434 void ipcSetDataReference(const uint8_t* data, size_t dataSize,
435 const binder_size_t* objects, size_t objectsCount,
436 release_func relFunc, void* relCookie);
437
438 public:
439 void print(TextOutput& to, uint32_t flags = 0) const;
440
441 private:
442 Parcel(const Parcel& o);
443 Parcel& operator=(const Parcel& o);
444
445 status_t finishWrite(size_t len);
446 void releaseObjects();
447 void acquireObjects();
448 status_t growData(size_t len);
449 status_t restartWrite(size_t desired);
450 status_t continueWrite(size_t desired);
451 status_t writePointer(uintptr_t val);
452 status_t readPointer(uintptr_t *pArg) const;
453 uintptr_t readPointer() const;
454 void freeDataNoInit();
455 void initState();
456 void scanForFds() const;
457 status_t validateReadData(size_t len) const;
458 void updateWorkSourceRequestHeaderPosition() const;
459
460 status_t finishFlattenBinder(const sp<IBinder>& binder,
461 const flat_binder_object& flat);
462 status_t finishUnflattenBinder(const sp<IBinder>& binder, sp<IBinder>* out) const;
463 status_t flattenBinder(const sp<IBinder>& binder);
464 status_t unflattenBinder(sp<IBinder>* out) const;
465
466 template<class T>
467 status_t readAligned(T *pArg) const;
468
469 template<class T> T readAligned() const;
470
471 template<class T>
472 status_t writeAligned(T val);
473
474 status_t writeRawNullableParcelable(const Parcelable*
475 parcelable);
476
477 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0>
478 status_t writeEnum(const T& val);
479 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0>
480 status_t writeEnum(const T& val);
481
482 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0>
483 status_t readEnum(T* pArg) const;
484 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0>
485 status_t readEnum(T* pArg) const;
486
487 status_t writeByteVectorInternal(const int8_t* data, size_t size);
488 template<typename T>
489 status_t readByteVectorInternal(std::vector<T>* val, size_t size) const;
490
491 template<typename T, typename U>
492 status_t unsafeReadTypedVector(std::vector<T>* val,
493 status_t(Parcel::*read_func)(U*) const) const;
494 template<typename T>
495 status_t readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
496 status_t(Parcel::*read_func)(T*) const) const;
497 template<typename T>
498 status_t readTypedVector(std::vector<T>* val,
499 status_t(Parcel::*read_func)(T*) const) const;
500 template<typename T, typename U>
501 status_t unsafeWriteTypedVector(const std::vector<T>& val,
502 status_t(Parcel::*write_func)(U));
503 template<typename T>
504 status_t writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
505 status_t(Parcel::*write_func)(const T&));
506 template<typename T>
507 status_t writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
508 status_t(Parcel::*write_func)(T));
509 template<typename T>
510 status_t writeTypedVector(const std::vector<T>& val,
511 status_t(Parcel::*write_func)(const T&));
512 template<typename T>
513 status_t writeTypedVector(const std::vector<T>& val,
514 status_t(Parcel::*write_func)(T));
515
516 status_t mError;
517 uint8_t* mData;
518 size_t mDataSize;
519 size_t mDataCapacity;
520 mutable size_t mDataPos;
521 binder_size_t* mObjects;
522 size_t mObjectsSize;
523 size_t mObjectsCapacity;
524 mutable size_t mNextObjectHint;
525 mutable bool mObjectsSorted;
526
527 mutable bool mRequestHeaderPresent;
528 mutable size_t mWorkSourceRequestHeaderPosition;
529
530 mutable bool mFdsKnown;
531 mutable bool mHasFds;
532 bool mAllowFds;
533
534 release_func mOwner;
535 void* mOwnerCookie;
536
537 class Blob {
538 public:
539 Blob();
540 ~Blob();
541
542 void clear();
543 void release();
size()544 inline size_t size() const { return mSize; }
fd()545 inline int fd() const { return mFd; }
isMutable()546 inline bool isMutable() const { return mMutable; }
547
548 protected:
549 void init(int fd, void* data, size_t size, bool isMutable);
550
551 int mFd; // owned by parcel so not closed when released
552 void* mData;
553 size_t mSize;
554 bool mMutable;
555 };
556
557 #if defined(__clang__)
558 #pragma clang diagnostic push
559 #pragma clang diagnostic ignored "-Wweak-vtables"
560 #endif
561
562 // FlattenableHelperInterface and FlattenableHelper avoid generating a vtable entry in objects
563 // following Flattenable template/protocol.
564 class FlattenableHelperInterface {
565 protected:
~FlattenableHelperInterface()566 ~FlattenableHelperInterface() { }
567 public:
568 virtual size_t getFlattenedSize() const = 0;
569 virtual size_t getFdCount() const = 0;
570 virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const = 0;
571 virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) = 0;
572 };
573
574 #if defined(__clang__)
575 #pragma clang diagnostic pop
576 #endif
577
578 // Concrete implementation of FlattenableHelperInterface that delegates virtual calls to the
579 // specified class T implementing the Flattenable protocol. It "virtualizes" a compile-time
580 // protocol.
581 template<typename T>
582 class FlattenableHelper : public FlattenableHelperInterface {
583 friend class Parcel;
584 const Flattenable<T>& val;
FlattenableHelper(const Flattenable<T> & _val)585 explicit FlattenableHelper(const Flattenable<T>& _val) : val(_val) { }
586
587 protected:
588 ~FlattenableHelper() = default;
589 public:
getFlattenedSize()590 virtual size_t getFlattenedSize() const {
591 return val.getFlattenedSize();
592 }
getFdCount()593 virtual size_t getFdCount() const {
594 return val.getFdCount();
595 }
flatten(void * buffer,size_t size,int * fds,size_t count)596 virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const {
597 return val.flatten(buffer, size, fds, count);
598 }
unflatten(void const * buffer,size_t size,int const * fds,size_t count)599 virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) {
600 return const_cast<Flattenable<T>&>(val).unflatten(buffer, size, fds, count);
601 }
602 };
603 status_t write(const FlattenableHelperInterface& val);
604 status_t read(FlattenableHelperInterface& val) const;
605
606 public:
607 class ReadableBlob : public Blob {
608 friend class Parcel;
609 public:
data()610 inline const void* data() const { return mData; }
mutableData()611 inline void* mutableData() { return isMutable() ? mData : nullptr; }
612 };
613
614 class WritableBlob : public Blob {
615 friend class Parcel;
616 public:
data()617 inline void* data() { return mData; }
618 };
619
620 private:
621 size_t mOpenAshmemSize;
622
623 public:
624 // TODO: Remove once ABI can be changed.
625 size_t getBlobAshmemSize() const;
626 size_t getOpenAshmemSize() const;
627 };
628
629 // ---------------------------------------------------------------------------
630
631 template<typename T>
write(const Flattenable<T> & val)632 status_t Parcel::write(const Flattenable<T>& val) {
633 const FlattenableHelper<T> helper(val);
634 return write(helper);
635 }
636
637 template<typename T>
write(const LightFlattenable<T> & val)638 status_t Parcel::write(const LightFlattenable<T>& val) {
639 size_t size(val.getFlattenedSize());
640 if (!val.isFixedSize()) {
641 if (size > INT32_MAX) {
642 return BAD_VALUE;
643 }
644 status_t err = writeInt32(static_cast<int32_t>(size));
645 if (err != NO_ERROR) {
646 return err;
647 }
648 }
649 if (size) {
650 void* buffer = writeInplace(size);
651 if (buffer == nullptr)
652 return NO_MEMORY;
653 return val.flatten(buffer, size);
654 }
655 return NO_ERROR;
656 }
657
658 template<typename T>
read(Flattenable<T> & val)659 status_t Parcel::read(Flattenable<T>& val) const {
660 FlattenableHelper<T> helper(val);
661 return read(helper);
662 }
663
664 template<typename T>
read(LightFlattenable<T> & val)665 status_t Parcel::read(LightFlattenable<T>& val) const {
666 size_t size;
667 if (val.isFixedSize()) {
668 size = val.getFlattenedSize();
669 } else {
670 int32_t s;
671 status_t err = readInt32(&s);
672 if (err != NO_ERROR) {
673 return err;
674 }
675 size = static_cast<size_t>(s);
676 }
677 if (size) {
678 void const* buffer = readInplace(size);
679 return buffer == nullptr ? NO_MEMORY :
680 val.unflatten(buffer, size);
681 }
682 return NO_ERROR;
683 }
684
685 template<typename T>
writeVectorSize(const std::vector<T> & val)686 status_t Parcel::writeVectorSize(const std::vector<T>& val) {
687 if (val.size() > INT32_MAX) {
688 return BAD_VALUE;
689 }
690 return writeInt32(static_cast<int32_t>(val.size()));
691 }
692
693 template<typename T>
writeVectorSize(const std::unique_ptr<std::vector<T>> & val)694 status_t Parcel::writeVectorSize(const std::unique_ptr<std::vector<T>>& val) {
695 if (!val) {
696 return writeInt32(-1);
697 }
698
699 return writeVectorSize(*val);
700 }
701
702 template<typename T>
resizeOutVector(std::vector<T> * val)703 status_t Parcel::resizeOutVector(std::vector<T>* val) const {
704 int32_t size;
705 status_t err = readInt32(&size);
706 if (err != NO_ERROR) {
707 return err;
708 }
709
710 if (size < 0) {
711 return UNEXPECTED_NULL;
712 }
713 val->resize(size_t(size));
714 return OK;
715 }
716
717 template<typename T>
resizeOutVector(std::unique_ptr<std::vector<T>> * val)718 status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
719 int32_t size;
720 status_t err = readInt32(&size);
721 if (err != NO_ERROR) {
722 return err;
723 }
724
725 val->reset();
726 if (size >= 0) {
727 val->reset(new std::vector<T>(size_t(size)));
728 }
729
730 return OK;
731 }
732
733 template<typename T>
reserveOutVector(std::vector<T> * val,size_t * size)734 status_t Parcel::reserveOutVector(std::vector<T>* val, size_t* size) const {
735 int32_t read_size;
736 status_t err = readInt32(&read_size);
737 if (err != NO_ERROR) {
738 return err;
739 }
740
741 if (read_size < 0) {
742 return UNEXPECTED_NULL;
743 }
744 *size = static_cast<size_t>(read_size);
745 val->reserve(*size);
746 return OK;
747 }
748
749 template<typename T>
reserveOutVector(std::unique_ptr<std::vector<T>> * val,size_t * size)750 status_t Parcel::reserveOutVector(std::unique_ptr<std::vector<T>>* val,
751 size_t* size) const {
752 int32_t read_size;
753 status_t err = readInt32(&read_size);
754 if (err != NO_ERROR) {
755 return err;
756 }
757
758 if (read_size >= 0) {
759 *size = static_cast<size_t>(read_size);
760 val->reset(new std::vector<T>());
761 (*val)->reserve(*size);
762 } else {
763 val->reset();
764 }
765
766 return OK;
767 }
768
769 template<typename T>
readStrongBinder(sp<T> * val)770 status_t Parcel::readStrongBinder(sp<T>* val) const {
771 sp<IBinder> tmp;
772 status_t ret = readStrongBinder(&tmp);
773
774 if (ret == OK) {
775 *val = interface_cast<T>(tmp);
776
777 if (val->get() == nullptr) {
778 return UNKNOWN_ERROR;
779 }
780 }
781
782 return ret;
783 }
784
785 template<typename T>
readNullableStrongBinder(sp<T> * val)786 status_t Parcel::readNullableStrongBinder(sp<T>* val) const {
787 sp<IBinder> tmp;
788 status_t ret = readNullableStrongBinder(&tmp);
789
790 if (ret == OK) {
791 *val = interface_cast<T>(tmp);
792
793 if (val->get() == nullptr && tmp.get() != nullptr) {
794 ret = UNKNOWN_ERROR;
795 }
796 }
797
798 return ret;
799 }
800
801 template<typename T, typename U>
unsafeReadTypedVector(std::vector<T> * val,status_t (Parcel::* read_func)(U *)const)802 status_t Parcel::unsafeReadTypedVector(
803 std::vector<T>* val,
804 status_t(Parcel::*read_func)(U*) const) const {
805 int32_t size;
806 status_t status = this->readInt32(&size);
807
808 if (status != OK) {
809 return status;
810 }
811
812 if (size < 0) {
813 return UNEXPECTED_NULL;
814 }
815
816 if (val->max_size() < static_cast<size_t>(size)) {
817 return NO_MEMORY;
818 }
819
820 val->resize(static_cast<size_t>(size));
821
822 if (val->size() < static_cast<size_t>(size)) {
823 return NO_MEMORY;
824 }
825
826 for (auto& v: *val) {
827 status = (this->*read_func)(&v);
828
829 if (status != OK) {
830 return status;
831 }
832 }
833
834 return OK;
835 }
836
837 template<typename T>
readTypedVector(std::vector<T> * val,status_t (Parcel::* read_func)(T *)const)838 status_t Parcel::readTypedVector(std::vector<T>* val,
839 status_t(Parcel::*read_func)(T*) const) const {
840 return unsafeReadTypedVector(val, read_func);
841 }
842
843 template<typename T>
readNullableTypedVector(std::unique_ptr<std::vector<T>> * val,status_t (Parcel::* read_func)(T *)const)844 status_t Parcel::readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
845 status_t(Parcel::*read_func)(T*) const) const {
846 const size_t start = dataPosition();
847 int32_t size;
848 status_t status = readInt32(&size);
849 val->reset();
850
851 if (status != OK || size < 0) {
852 return status;
853 }
854
855 setDataPosition(start);
856 val->reset(new std::vector<T>());
857
858 status = unsafeReadTypedVector(val->get(), read_func);
859
860 if (status != OK) {
861 val->reset();
862 }
863
864 return status;
865 }
866
867 template<typename T, typename U>
unsafeWriteTypedVector(const std::vector<T> & val,status_t (Parcel::* write_func)(U))868 status_t Parcel::unsafeWriteTypedVector(const std::vector<T>& val,
869 status_t(Parcel::*write_func)(U)) {
870 if (val.size() > std::numeric_limits<int32_t>::max()) {
871 return BAD_VALUE;
872 }
873
874 status_t status = this->writeInt32(static_cast<int32_t>(val.size()));
875
876 if (status != OK) {
877 return status;
878 }
879
880 for (const auto& item : val) {
881 status = (this->*write_func)(item);
882
883 if (status != OK) {
884 return status;
885 }
886 }
887
888 return OK;
889 }
890
891 template<typename T>
writeTypedVector(const std::vector<T> & val,status_t (Parcel::* write_func)(const T &))892 status_t Parcel::writeTypedVector(const std::vector<T>& val,
893 status_t(Parcel::*write_func)(const T&)) {
894 return unsafeWriteTypedVector(val, write_func);
895 }
896
897 template<typename T>
writeTypedVector(const std::vector<T> & val,status_t (Parcel::* write_func)(T))898 status_t Parcel::writeTypedVector(const std::vector<T>& val,
899 status_t(Parcel::*write_func)(T)) {
900 return unsafeWriteTypedVector(val, write_func);
901 }
902
903 template<typename T>
writeNullableTypedVector(const std::unique_ptr<std::vector<T>> & val,status_t (Parcel::* write_func)(const T &))904 status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
905 status_t(Parcel::*write_func)(const T&)) {
906 if (val.get() == nullptr) {
907 return this->writeInt32(-1);
908 }
909
910 return unsafeWriteTypedVector(*val, write_func);
911 }
912
913 template<typename T>
writeNullableTypedVector(const std::unique_ptr<std::vector<T>> & val,status_t (Parcel::* write_func)(T))914 status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
915 status_t(Parcel::*write_func)(T)) {
916 if (val.get() == nullptr) {
917 return this->writeInt32(-1);
918 }
919
920 return unsafeWriteTypedVector(*val, write_func);
921 }
922
923 template<typename T>
readParcelableVector(std::vector<T> * val)924 status_t Parcel::readParcelableVector(std::vector<T>* val) const {
925 return unsafeReadTypedVector<T, Parcelable>(val, &Parcel::readParcelable);
926 }
927
928 template<typename T>
readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>> * val)929 status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const {
930 const size_t start = dataPosition();
931 int32_t size;
932 status_t status = readInt32(&size);
933 val->reset();
934
935 if (status != OK || size < 0) {
936 return status;
937 }
938
939 setDataPosition(start);
940 val->reset(new std::vector<std::unique_ptr<T>>());
941
942 status = unsafeReadTypedVector(val->get(), &Parcel::readParcelable<T>);
943
944 if (status != OK) {
945 val->reset();
946 }
947
948 return status;
949 }
950
951 template<typename T>
readParcelable(std::unique_ptr<T> * parcelable)952 status_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const {
953 const size_t start = dataPosition();
954 int32_t present;
955 status_t status = readInt32(&present);
956 parcelable->reset();
957
958 if (status != OK || !present) {
959 return status;
960 }
961
962 setDataPosition(start);
963 parcelable->reset(new T());
964
965 status = readParcelable(parcelable->get());
966
967 if (status != OK) {
968 parcelable->reset();
969 }
970
971 return status;
972 }
973
974 template<typename T>
writeNullableParcelable(const std::unique_ptr<T> & parcelable)975 status_t Parcel::writeNullableParcelable(const std::unique_ptr<T>& parcelable) {
976 return writeRawNullableParcelable(parcelable.get());
977 }
978
979 template<typename T>
writeParcelableVector(const std::vector<T> & val)980 status_t Parcel::writeParcelableVector(const std::vector<T>& val) {
981 return unsafeWriteTypedVector<T,const Parcelable&>(val, &Parcel::writeParcelable);
982 }
983
984 template<typename T>
writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>> & val)985 status_t Parcel::writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val) {
986 if (val.get() == nullptr) {
987 return this->writeInt32(-1);
988 }
989
990 return unsafeWriteTypedVector(*val, &Parcel::writeNullableParcelable<T>);
991 }
992
993 template<typename T>
writeParcelableVector(const std::shared_ptr<std::vector<std::unique_ptr<T>>> & val)994 status_t Parcel::writeParcelableVector(const std::shared_ptr<std::vector<std::unique_ptr<T>>>& val) {
995 if (val.get() == nullptr) {
996 return this->writeInt32(-1);
997 }
998
999 return unsafeWriteTypedVector(*val, &Parcel::writeNullableParcelable<T>);
1000 }
1001
1002 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>>
writeEnum(const T & val)1003 status_t Parcel::writeEnum(const T& val) {
1004 return writeInt32(static_cast<int32_t>(val));
1005 }
1006 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>>
writeEnum(const T & val)1007 status_t Parcel::writeEnum(const T& val) {
1008 return writeInt64(static_cast<int64_t>(val));
1009 }
1010
1011 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
writeEnumVector(const std::vector<T> & val)1012 status_t Parcel::writeEnumVector(const std::vector<T>& val) {
1013 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
1014 }
1015 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
writeEnumVector(const std::unique_ptr<std::vector<T>> & val)1016 status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
1017 if (!val) return writeInt32(-1);
1018 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
1019 }
1020 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
writeEnumVector(const std::vector<T> & val)1021 status_t Parcel::writeEnumVector(const std::vector<T>& val) {
1022 return writeTypedVector(val, &Parcel::writeEnum);
1023 }
1024 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
writeEnumVector(const std::unique_ptr<std::vector<T>> & val)1025 status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
1026 return writeNullableTypedVector(val, &Parcel::writeEnum);
1027 }
1028
1029 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>>
readEnum(T * pArg)1030 status_t Parcel::readEnum(T* pArg) const {
1031 return readInt32(reinterpret_cast<int32_t *>(pArg));
1032 }
1033 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>>
readEnum(T * pArg)1034 status_t Parcel::readEnum(T* pArg) const {
1035 return readInt64(reinterpret_cast<int64_t *>(pArg));
1036 }
1037
1038 template<typename T>
readByteVectorInternal(std::vector<T> * val,size_t size)1039 inline status_t Parcel::readByteVectorInternal(std::vector<T>* val, size_t size) const {
1040 // readByteVectorInternal expects a vector that has been reserved (but not
1041 // resized) to have the provided size.
1042 const T* data = reinterpret_cast<const T*>(readInplace(size));
1043 if (!data) return BAD_VALUE;
1044 val->clear();
1045 val->insert(val->begin(), data, data+size);
1046 return NO_ERROR;
1047 }
1048
1049 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
readEnumVector(std::vector<T> * val)1050 status_t Parcel::readEnumVector(std::vector<T>* val) const {
1051 size_t size;
1052 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1053 return readByteVectorInternal(val, size);
1054 }
1055 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
readEnumVector(std::unique_ptr<std::vector<T>> * val)1056 status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const {
1057 size_t size;
1058 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1059 if (val->get() == nullptr) {
1060 // reserveOutVector does not create the out vector if size is < 0.
1061 // This occurs when writing a null Enum vector.
1062 return OK;
1063 }
1064 return readByteVectorInternal(val->get(), size);
1065 }
1066 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
readEnumVector(std::vector<T> * val)1067 status_t Parcel::readEnumVector(std::vector<T>* val) const {
1068 return readTypedVector(val, &Parcel::readEnum);
1069 }
1070 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
readEnumVector(std::unique_ptr<std::vector<T>> * val)1071 status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const {
1072 return readNullableTypedVector(val, &Parcel::readEnum);
1073 }
1074
1075 // ---------------------------------------------------------------------------
1076
1077 inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
1078 {
1079 parcel.print(to);
1080 return to;
1081 }
1082
1083 } // namespace android
1084
1085 // ---------------------------------------------------------------------------
1086
1087 #endif // ANDROID_PARCEL_H
1088