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