Parcel.h revision 41a0f2f86c0ca7d2fef50aef6215987f445a7231
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 <cutils/native_handle.h> 21#include <utils/Errors.h> 22#include <utils/RefBase.h> 23#include <utils/String16.h> 24#include <utils/Vector.h> 25#include <utils/Flattenable.h> 26#include <linux/binder.h> 27 28// --------------------------------------------------------------------------- 29namespace android { 30 31template <typename T> class Flattenable; 32template <typename T> class LightFlattenable; 33class IBinder; 34class IPCThreadState; 35class ProcessState; 36class String8; 37class TextOutput; 38 39class Parcel { 40 friend class IPCThreadState; 41public: 42 class ReadableBlob; 43 class WritableBlob; 44 45 Parcel(); 46 ~Parcel(); 47 48 const uint8_t* data() const; 49 size_t dataSize() const; 50 size_t dataAvail() const; 51 size_t dataPosition() const; 52 size_t dataCapacity() const; 53 54 status_t setDataSize(size_t size); 55 void setDataPosition(size_t pos) const; 56 status_t setDataCapacity(size_t size); 57 58 status_t setData(const uint8_t* buffer, size_t len); 59 60 status_t appendFrom(const Parcel *parcel, 61 size_t start, size_t len); 62 63 bool pushAllowFds(bool allowFds); 64 void restoreAllowFds(bool lastValue); 65 66 bool hasFileDescriptors() const; 67 68 // Writes the RPC header. 69 status_t writeInterfaceToken(const String16& interface); 70 71 // Parses the RPC header, returning true if the interface name 72 // in the header matches the expected interface from the caller. 73 // 74 // Additionally, enforceInterface does part of the work of 75 // propagating the StrictMode policy mask, populating the current 76 // IPCThreadState, which as an optimization may optionally be 77 // passed in. 78 bool enforceInterface(const String16& interface, 79 IPCThreadState* threadState = NULL) const; 80 bool checkInterface(IBinder*) const; 81 82 void freeData(); 83 84private: 85 const binder_size_t* objects() const; 86 87public: 88 size_t objectsCount() const; 89 90 status_t errorCheck() const; 91 void setError(status_t err); 92 93 status_t write(const void* data, size_t len); 94 void* writeInplace(size_t len); 95 status_t writeUnpadded(const void* data, size_t len); 96 status_t writeInt32(int32_t val); 97 status_t writeUint32(uint32_t val); 98 status_t writeInt64(int64_t val); 99 status_t writeFloat(float val); 100 status_t writeDouble(double val); 101 status_t writeCString(const char* str); 102 status_t writeString8(const String8& str); 103 status_t writeString16(const String16& str); 104 status_t writeString16(const char16_t* str, size_t len); 105 status_t writeStrongBinder(const sp<IBinder>& val); 106 status_t writeWeakBinder(const wp<IBinder>& val); 107 status_t writeInt32Array(size_t len, const int32_t *val); 108 status_t writeByteArray(size_t len, const uint8_t *val); 109 110 template<typename T> 111 status_t write(const Flattenable<T>& val); 112 113 template<typename T> 114 status_t write(const LightFlattenable<T>& val); 115 116 117 // Place a native_handle into the parcel (the native_handle's file- 118 // descriptors are dup'ed, so it is safe to delete the native_handle 119 // when this function returns). 120 // Doesn't take ownership of the native_handle. 121 status_t writeNativeHandle(const native_handle* handle); 122 123 // Place a file descriptor into the parcel. The given fd must remain 124 // valid for the lifetime of the parcel. 125 // The Parcel does not take ownership of the given fd unless you ask it to. 126 status_t writeFileDescriptor(int fd, bool takeOwnership = false); 127 128 // Place a file descriptor into the parcel. A dup of the fd is made, which 129 // will be closed once the parcel is destroyed. 130 status_t writeDupFileDescriptor(int fd); 131 132 // Writes a raw fd and optional comm channel fd to the parcel as a ParcelFileDescriptor. 133 // A dup's of the fds are made, which will be closed once the parcel is destroyed. 134 // Null values are passed as -1. 135 status_t writeParcelFileDescriptor(int fd, int commChannel = -1); 136 137 // Writes a blob to the parcel. 138 // If the blob is small, then it is stored in-place, otherwise it is 139 // transferred by way of an anonymous shared memory region. 140 // The caller should call release() on the blob after writing its contents. 141 status_t writeBlob(size_t len, WritableBlob* outBlob); 142 143 status_t writeObject(const flat_binder_object& val, bool nullMetaData); 144 145 // Like Parcel.java's writeNoException(). Just writes a zero int32. 146 // Currently the native implementation doesn't do any of the StrictMode 147 // stack gathering and serialization that the Java implementation does. 148 status_t writeNoException(); 149 150 void remove(size_t start, size_t amt); 151 152 status_t read(void* outData, size_t len) const; 153 const void* readInplace(size_t len) const; 154 int32_t readInt32() const; 155 status_t readInt32(int32_t *pArg) const; 156 uint32_t readUint32() const; 157 status_t readUint32(uint32_t *pArg) const; 158 int64_t readInt64() const; 159 status_t readInt64(int64_t *pArg) const; 160 float readFloat() const; 161 status_t readFloat(float *pArg) const; 162 double readDouble() const; 163 status_t readDouble(double *pArg) const; 164 intptr_t readIntPtr() const; 165 status_t readIntPtr(intptr_t *pArg) const; 166 167 const char* readCString() const; 168 String8 readString8() const; 169 String16 readString16() const; 170 const char16_t* readString16Inplace(size_t* outLen) const; 171 sp<IBinder> readStrongBinder() const; 172 wp<IBinder> readWeakBinder() const; 173 174 template<typename T> 175 status_t read(Flattenable<T>& val) const; 176 177 template<typename T> 178 status_t read(LightFlattenable<T>& val) const; 179 180 // Like Parcel.java's readExceptionCode(). Reads the first int32 181 // off of a Parcel's header, returning 0 or the negative error 182 // code on exceptions, but also deals with skipping over rich 183 // response headers. Callers should use this to read & parse the 184 // response headers rather than doing it by hand. 185 int32_t readExceptionCode() const; 186 187 // Retrieve native_handle from the parcel. This returns a copy of the 188 // parcel's native_handle (the caller takes ownership). The caller 189 // must free the native_handle with native_handle_close() and 190 // native_handle_delete(). 191 native_handle* readNativeHandle() const; 192 193 194 // Retrieve a file descriptor from the parcel. This returns the raw fd 195 // in the parcel, which you do not own -- use dup() to get your own copy. 196 int readFileDescriptor() const; 197 198 // Reads a ParcelFileDescriptor from the parcel. Returns the raw fd as 199 // the result, and the optional comm channel fd in outCommChannel. 200 // Null values are returned as -1. 201 int readParcelFileDescriptor(int& outCommChannel) const; 202 203 // Reads a blob from the parcel. 204 // The caller should call release() on the blob after reading its contents. 205 status_t readBlob(size_t len, ReadableBlob* outBlob) const; 206 207 const flat_binder_object* readObject(bool nullMetaData) const; 208 209 // Explicitly close all file descriptors in the parcel. 210 void closeFileDescriptors(); 211 212private: 213 typedef void (*release_func)(Parcel* parcel, 214 const uint8_t* data, size_t dataSize, 215 const binder_size_t* objects, size_t objectsSize, 216 void* cookie); 217 218 uintptr_t ipcData() const; 219 size_t ipcDataSize() const; 220 uintptr_t ipcObjects() const; 221 size_t ipcObjectsCount() const; 222 void ipcSetDataReference(const uint8_t* data, size_t dataSize, 223 const binder_size_t* objects, size_t objectsCount, 224 release_func relFunc, void* relCookie); 225 226public: 227 void print(TextOutput& to, uint32_t flags = 0) const; 228 229private: 230 Parcel(const Parcel& o); 231 Parcel& operator=(const Parcel& o); 232 233 status_t finishWrite(size_t len); 234 void releaseObjects(); 235 void acquireObjects(); 236 status_t growData(size_t len); 237 status_t restartWrite(size_t desired); 238 status_t continueWrite(size_t desired); 239 status_t writePointer(uintptr_t val); 240 status_t readPointer(uintptr_t *pArg) const; 241 uintptr_t readPointer() const; 242 void freeDataNoInit(); 243 void initState(); 244 void scanForFds() const; 245 246 template<class T> 247 status_t readAligned(T *pArg) const; 248 249 template<class T> T readAligned() const; 250 251 template<class T> 252 status_t writeAligned(T val); 253 254 status_t mError; 255 uint8_t* mData; 256 size_t mDataSize; 257 size_t mDataCapacity; 258 mutable size_t mDataPos; 259 binder_size_t* mObjects; 260 size_t mObjectsSize; 261 size_t mObjectsCapacity; 262 mutable size_t mNextObjectHint; 263 264 mutable bool mFdsKnown; 265 mutable bool mHasFds; 266 bool mAllowFds; 267 268 release_func mOwner; 269 void* mOwnerCookie; 270 271 class Blob { 272 public: 273 Blob(); 274 ~Blob(); 275 276 void release(); 277 inline size_t size() const { return mSize; } 278 279 protected: 280 void init(bool mapped, void* data, size_t size); 281 void clear(); 282 283 bool mMapped; 284 void* mData; 285 size_t mSize; 286 }; 287 288 class FlattenableHelperInterface { 289 protected: 290 ~FlattenableHelperInterface() { } 291 public: 292 virtual size_t getFlattenedSize() const = 0; 293 virtual size_t getFdCount() const = 0; 294 virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const = 0; 295 virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) = 0; 296 }; 297 298 template<typename T> 299 class FlattenableHelper : public FlattenableHelperInterface { 300 friend class Parcel; 301 const Flattenable<T>& val; 302 explicit FlattenableHelper(const Flattenable<T>& val) : val(val) { } 303 304 public: 305 virtual size_t getFlattenedSize() const { 306 return val.getFlattenedSize(); 307 } 308 virtual size_t getFdCount() const { 309 return val.getFdCount(); 310 } 311 virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const { 312 return val.flatten(buffer, size, fds, count); 313 } 314 virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) { 315 return const_cast<Flattenable<T>&>(val).unflatten(buffer, size, fds, count); 316 } 317 }; 318 status_t write(const FlattenableHelperInterface& val); 319 status_t read(FlattenableHelperInterface& val) const; 320 321public: 322 class ReadableBlob : public Blob { 323 friend class Parcel; 324 public: 325 inline const void* data() const { return mData; } 326 }; 327 328 class WritableBlob : public Blob { 329 friend class Parcel; 330 public: 331 inline void* data() { return mData; } 332 }; 333}; 334 335// --------------------------------------------------------------------------- 336 337template<typename T> 338status_t Parcel::write(const Flattenable<T>& val) { 339 const FlattenableHelper<T> helper(val); 340 return write(helper); 341} 342 343template<typename T> 344status_t Parcel::write(const LightFlattenable<T>& val) { 345 size_t size(val.getFlattenedSize()); 346 if (!val.isFixedSize()) { 347 status_t err = writeInt32(size); 348 if (err != NO_ERROR) { 349 return err; 350 } 351 } 352 if (size) { 353 void* buffer = writeInplace(size); 354 if (buffer == NULL) 355 return NO_MEMORY; 356 return val.flatten(buffer, size); 357 } 358 return NO_ERROR; 359} 360 361template<typename T> 362status_t Parcel::read(Flattenable<T>& val) const { 363 FlattenableHelper<T> helper(val); 364 return read(helper); 365} 366 367template<typename T> 368status_t Parcel::read(LightFlattenable<T>& val) const { 369 size_t size; 370 if (val.isFixedSize()) { 371 size = val.getFlattenedSize(); 372 } else { 373 int32_t s; 374 status_t err = readInt32(&s); 375 if (err != NO_ERROR) { 376 return err; 377 } 378 size = s; 379 } 380 if (size) { 381 void const* buffer = readInplace(size); 382 return buffer == NULL ? NO_MEMORY : 383 val.unflatten(buffer, size); 384 } 385 return NO_ERROR; 386} 387 388// --------------------------------------------------------------------------- 389 390inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel) 391{ 392 parcel.print(to); 393 return to; 394} 395 396// --------------------------------------------------------------------------- 397 398// Generic acquire and release of objects. 399void acquire_object(const sp<ProcessState>& proc, 400 const flat_binder_object& obj, const void* who); 401void release_object(const sp<ProcessState>& proc, 402 const flat_binder_object& obj, const void* who); 403 404void flatten_binder(const sp<ProcessState>& proc, 405 const sp<IBinder>& binder, flat_binder_object* out); 406void flatten_binder(const sp<ProcessState>& proc, 407 const wp<IBinder>& binder, flat_binder_object* out); 408status_t unflatten_binder(const sp<ProcessState>& proc, 409 const flat_binder_object& flat, sp<IBinder>* out); 410status_t unflatten_binder(const sp<ProcessState>& proc, 411 const flat_binder_object& flat, wp<IBinder>* out); 412 413}; // namespace android 414 415// --------------------------------------------------------------------------- 416 417#endif // ANDROID_PARCEL_H 418