一.先从Serialize说起
       我们都知道JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。

      二.Android中的新的序列化机制
       在Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC(进程间通信)机制,必然要求使用性能更出色的对象传输方式。在这样的环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。

      三.Parcel类的背后
       在Framework中有parcel类,源码路径是:Frameworks/base/core/java/android/os/Parcel.java
       典型的源码片断如下:

java代码:
  1. /**
  2. * Write an integer value into the parcel at the current dataPosition(),
  3. * growing dataCapacity() if needed.
  4. */
  5. public final native void writeInt(int val);

  6. /**
  7. * Write a long integer value into the parcel at the current dataPosition(),
  8. * growing dataCapacity() if needed.
  9. */
  10. public final native void writeLong(long val);
复制代码
        从中我们看到,从这个源程序文件中我们看不到真正的功能是如何实现的,必须透过JNI往下走了。于是,Frameworks/base/core/jni/android_util_Binder.cpp中找到了线索

java代码:
  1. static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
  2. {
  3. Parcel* parcel = parcelForJavaObject(env, clazz);
  4. if (parcel != NULL) {
  5. const status_t err = parcel->writeInt32(val);
  6. if (err != NO_ERROR) {
  7. jniThrowException(env, “java/lang/OutOfMemoryError”, NULL);
  8. }
  9. }
  10. }

  11. static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
  12. {
  13. Parcel* parcel = parcelForJavaObject(env, clazz);
  14. if (parcel != NULL) {
  15. const status_t err = parcel->writeInt64(val);
  16. if (err != NO_ERROR) {
  17. jniThrowException(env, “java/lang/OutOfMemoryError”, NULL);
  18. }
  19. }
  20. }
复制代码
       从这里我们可以得到的信息是函数的实现依赖于Parcel指针,因此还需要找到Parcel的类定义,注意,这里的类已经是用C++语言实现的了。

       找到Frameworks/base/include/binder/parcel.h和Frameworks/base/libs/binder/parcel.cpp。终于找到了最终的实现代码了。

       有兴趣的朋友可以自己读一下,不难理解,这里把基本的思路总结一下:

       1. 整个读写全是在内存中进行,主要是通过malloc()、realloc()、memcpy()等内存操作进行,所以效率比JAVA序列化中使用外部存储器会高很多;
       2. 读写时是4字节对齐的,可以看到#define PAD_SIZE(s) (((s)+3)&~3)这句宏定义就是在做这件事情;
       3. 如果预分配的空间不够时newSize = ((mDataSize+len)*3)/2;会一次多分配50%;
       4. 对于普通数据,使用的是mData内存地址,对于IBinder类型的数据以及FileDescriptor使用的是mObjects内存地址。后者是通过flatten_binder()和unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new一个新对象。

java代码:
  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. #ifndef ANDROID_PARCEL_H
  17. #define ANDROID_PARCEL_H

  18. #include
  19. #include
  20. #include
  21. #include
  22. #include
  23. // —————————————————————————
  24. namespace android {

  25. class IBinder;
  26. class ProcessState;
  27. class String8;
  28. class TextOutput;
  29. class Flattenable;

  30. struct flat_binder_object; // defined in support_p/binder_module.h

  31. class Parcel
  32. {
  33. public:
  34. Parcel();
  35. ~Parcel();

  36. const uint8_t* data() const;
  37. size_t dataSize() const;
  38. size_t dataAvail() const;
  39. size_t dataPosition() const;
  40. size_t dataCapacity() const;

  41. status_t setDataSize(size_t size);
  42. void setDataPosition(size_t pos) const;
  43. status_t setDataCapacity(size_t size);

  44. status_t setData(const uint8_t* buffer, size_t len);

  45. status_t appendFrom(Parcel *parcel, size_t start, size_t len);

  46. bool hasFileDescriptors() const;
复制代码java代码:
  1. status_t writeInterfaceToken(const String16& interface);
  2. bool enforceInterface(const String16& interface) const;
  3. bool checkInterface(IBinder*) const;

  4. void freeData();

  5. const size_t* objects() const;
  6. size_t objectsCount() const;

  7. status_t errorCheck() const;
  8. void setError(status_t err);

  9. status_t write(const void* data, size_t len);
  10. void* writeInplace(size_t len);
  11. status_t writeUnpadded(const void* data, size_t len);
  12. status_t writeInt32(int32_t val);
  13. status_t writeInt64(int64_t val);
  14. status_t writeFloat(float val);
  15. status_t writeDouble(double val);
  16. status_t writeIntPtr(intptr_t val);
  17. status_t writeCString(const char* str);
  18. status_t writeString8(const String8& str);
  19. status_t writeString16(const String16& str);
  20. status_t writeString16(const char16_t* str, size_t len);
  21. status_t writeStrongBinder(const sp& val);
  22. status_t writeWeakBinder(const wp& val);
  23. status_t write(const Flattenable& val);

  24. // Place a native_handle into the parcel (the native_handle’s file-
  25. // descriptors are dup’ed, so it is safe to delete the native_handle
  26. // when this function returns).
  27. // Doesn’t take ownership of the native_handle.
  28. status_t writeNativeHandle(const native_handle* handle);

  29. // Place a file descriptor into the parcel. The given fd must remain
  30. // valid for the lifetime of the parcel.
  31. status_t writeFileDescriptor(int fd);

  32. // Place a file descriptor into the parcel. A dup of the fd is made, which
  33. // will be closed once the parcel is destroyed.
  34. status_t writeDupFileDescriptor(int fd);

  35. status_t writeObject(const flat_binder_object& val, bool nullMetaData);

  36. void remove(size_t start, size_t amt);

  37. status_t read(void* outData, size_t len) const;
  38. const void* readInplace(size_t len) const;
  39. int32_t readInt32() const;
  40. status_t readInt32(int32_t *pArg) const;
  41. int64_t readInt64() const;
  42. status_t readInt64(int64_t *pArg) const;
  43. float readFloat() const;
  44. status_t readFloat(float *pArg) const;
  45. double readDouble() const;
  46. status_t readDouble(double *pArg) const;
  47. intptr_t readIntPtr() const;
  48. status_t readIntPtr(intptr_t *pArg) const;

  49. const char* readCString() const;
  50. String8 readString8() const;
  51. String16 readString16() const;
  52. const char16_t* readString16Inplace(size_t* outLen) const;
  53. sp readStrongBinder() const;
  54. wp readWeakBinder() const;
  55. status_t read(Flattenable& val) const;

  56. // Retrieve native_handle from the parcel. This returns a copy of the
  57. // parcel’s native_handle (the caller takes ownership). The caller
  58. // must free the native_handle with native_handle_close() and
  59. // native_handle_delete().
  60. native_handle* readNativeHandle() const;

  61. // Retrieve a file descriptor from the parcel. This returns the raw fd
  62. // in the parcel, which you do not own — use dup() to get your own copy.
  63. int readFileDescriptor() const;

  64. const flat_binder_object* readObject(bool nullMetaData) const;

  65. // Explicitly close all file descriptors in the parcel.
  66. void closeFileDescriptors();

  67. typedef void (*release_func)(Parcel* parcel,
  68. const uint8_t* data, size_t dataSize,
  69. const size_t* objects, size_t objectsSize,
  70. void* cookie);

  71. const uint8_t* ipcData() const;
  72. size_t ipcDataSize() const;
  73. const size_t* ipcObjects() const;
  74. size_t ipcObjectsCount() const;
  75. void ipcSetDataReference(const uint8_t* data, size_t dataSize,
  76. const size_t* objects, size_t objectsCount,
  77. release_func relFunc, void* relCookie);

  78. void print(TextOutput& to, uint32_t flags = 0) const;

  79. private:
  80. Parcel(const Parcel& o);
  81. Parcel& operator=(const Parcel& o);

  82. status_t finishWrite(size_t len);
  83. void releaseObjects();
  84. void acquireObjects();
  85. status_t growData(size_t len);
  86. status_t restartWrite(size_t desired);
  87. status_t continueWrite(size_t desired);
  88. void freeDataNoInit();
  89. void initState();
  90. void scanForFds() const;

  91. template
  92. status_t readAligned(T *pArg) const;

  93. template T readAligned() const;

  94. template
  95. status_t writeAligned(T val);

  96. status_t mError;
  97. uint8_t* mData;
  98. size_t mDataSize;
  99. size_t mDataCapacity;
  100. mutable size_t mDataPos;
  101. size_t* mObjects;
  102. size_t mObjectsSize;
  103. size_t mObjectsCapacity;
  104. mutable size_t mNextObjectHint;

  105. mutable bool mFdsKnown;
  106. mutable bool mHasFds;

  107. release_func mOwner;
  108. void* mOwnerCookie;
  109. };
复制代码java代码:
  1. // —————————————————————————

  2. inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
  3. {
  4. parcel.print(to);
  5. return to;
  6. }

  7. // ---------------------------------------------------------------------------

  8. // Generic acquire and release of objects.
  9. void acquire_object(const sp& proc,
  10. const flat_binder_object& obj, const void* who);
  11. void release_object(const sp& proc,
  12. const flat_binder_object& obj, const void* who);

  13. void flatten_binder(const sp& proc,
  14. const sp& binder, flat_binder_object* out);
  15. void flatten_binder(const sp& proc,
  16. const wp& binder, flat_binder_object* out);
  17. status_t unflatten_binder(const sp& proc,
  18. const flat_binder_object& flat, sp* out);
  19. status_t unflatten_binder(const sp& proc,
  20. const flat_binder_object& flat, wp* out);

  21. }; // namespace android

  22. // —————————————————————————

  23. #endif // ANDROID_PARCEL_H

  24. view plain
  25. /*
  26. * Copyright (C) 2005 The Android Open Source Project
  27. *
  28. * Licensed under the Apache License, Version 2.0 (the “License”);
  29. * you may not use this file except in compliance with the License.
  30. * You may obtain a copy of the License at
  31. *
  32. * http://www.apache.org/licenses/LICENSE-2.0
  33. *
  34. * Unless required by applicable law or agreed to in writing, software
  35. * distributed under the License is distributed on an “AS IS” BASIS,
  36. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  37. * See the License for the specific language governing permissions and
  38. * limitations under the License.
  39. */

  40. #define LOG_TAG “Parcel”
  41. //#define LOG_NDEBUG 0

  42. #include
  43. #include
  44. #include
  45. #include
  46. #include
  47. #include
  48. #include
  49. #include
  50. #include
  51. #include
  52. #include
  53. #include
  54. #include
  55. #include
  56. #include
  57. #ifndef INT32_MAX
  58. #define INT32_MAX ((int32_t)(2147483647))
  59. #endif

  60. #define LOG_REFS(…)
  61. //#define LOG_REFS(…) LOG(LOG_DEBUG, “Parcel”, __VA_ARGS__)

  62. // —————————————————————————

  63. #define PAD_SIZE(s) (((s)+3)&~3)

  64. // XXX This can be made public if we want to provide
  65. // support for typed data.
  66. struct small_flat_data
  67. {
  68. uint32_t type;
  69. uint32_t data;
  70. };

  71. namespace android {

  72. void acquire_object(const sp& proc,
  73. const flat_binder_object& obj, const void* who)
  74. {
  75. switch (obj.type) {
  76. case BINDER_TYPE_BINDER:
  77. if (obj.binder) {
  78. LOG_REFS(“Parcel %p acquiring reference on local %p”, who, obj.cookie);
  79. static_cast(obj.cookie)->incStrong(who);
  80. }
  81. return;
  82. case BINDER_TYPE_WEAK_BINDER:
  83. if (obj.binder)
  84. static_cast(obj.binder)->incWeak(who);
  85. return;
  86. case BINDER_TYPE_HANDLE: {
  87. const sp b = proc->getStrongProxyForHandle(obj.handle);
  88. if (b != NULL) {
  89. LOG_REFS(“Parcel %p acquiring reference on remote %p”, who, b.get());
  90. b->incStrong(who);
  91. }
  92. return;
  93. }
  94. case BINDER_TYPE_WEAK_HANDLE: {
  95. const wp b = proc->getWeakProxyForHandle(obj.handle);
  96. if (b != NULL) b.get_refs()->incWeak(who);
  97. return;
  98. }
  99. case BINDER_TYPE_FD: {
  100. // intentionally blank — nothing to do to acquire this, but we do
  101. // recognize it as a legitimate object type.
  102. return;
  103. }
  104. }

  105. LOGD(“Invalid object type 0x%08lx”, obj.type);
  106. }

  107. void release_object(const sp& proc,
  108. const flat_binder_object& obj, const void* who)
  109. {
  110. switch (obj.type) {
  111. case BINDER_TYPE_BINDER:
  112. if (obj.binder) {
  113. LOG_REFS(“Parcel %p releasing reference on local %p”, who, obj.cookie);
  114. static_cast(obj.cookie)->decStrong(who);
  115. }
  116. return;
  117. case BINDER_TYPE_WEAK_BINDER:
  118. if (obj.binder)
  119. static_cast(obj.binder)->decWeak(who);
  120. return;
  121. case BINDER_TYPE_HANDLE: {
  122. const sp b = proc->getStrongProxyForHandle(obj.handle);
  123. if (b != NULL) {
  124. LOG_REFS(“Parcel %p releasing reference on remote %p”, who, b.get());
  125. b->decStrong(who);
  126. }
  127. return;
  128. }
  129. case BINDER_TYPE_WEAK_HANDLE: {
  130. const wp b = proc->getWeakProxyForHandle(obj.handle);
  131. if (b != NULL) b.get_refs()->decWeak(who);
  132. return;
  133. }
  134. case BINDER_TYPE_FD: {
  135. if (obj.cookie != (void*)0) close(obj.handle);
  136. return;
  137. }
  138. }

  139. LOGE(“Invalid object type 0x%08lx”, obj.type);
  140. }

  141. inline static status_t finish_flatten_binder(
  142. const sp& binder, const flat_binder_object& flat, Parcel* out)
  143. {
  144. return out->writeObject(flat, false);
  145. }

  146. status_t flatten_binder(const sp& proc,
  147. const sp& binder, Parcel* out)
  148. {
  149. flat_binder_object obj;

  150. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  151. if (binder != NULL) {
  152. IBinder *local = binder->localBinder();
  153. if (!local) {
  154. BpBinder *proxy = binder->remoteBinder();
  155. if (proxy == NULL) {
  156. LOGE(“null proxy”);
  157. }
  158. const int32_t handle = proxy ? proxy->handle() : 0;
  159. obj.type = BINDER_TYPE_HANDLE;
  160. obj.handle = handle;
  161. obj.cookie = NULL;
  162. } else {
  163. obj.type = BINDER_TYPE_BINDER;
  164. obj.binder = local->getWeakRefs();
  165. obj.cookie = local;
  166. }
  167. } else {
  168. obj.type = BINDER_TYPE_BINDER;
  169. obj.binder = NULL;
  170. obj.cookie = NULL;
  171. }

  172. return finish_flatten_binder(binder, obj, out);
  173. }

  174. status_t flatten_binder(const sp& proc,
  175. const wp& binder, Parcel* out)
  176. {
  177. flat_binder_object obj;

  178. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  179. if (binder != NULL) {
  180. sp real = binder.promote();
  181. if (real != NULL) {
  182. IBinder *local = real->localBinder();
  183. if (!local) {
  184. BpBinder *proxy = real->remoteBinder();
  185. if (proxy == NULL) {
  186. LOGE(“null proxy”);
  187. }
  188. const int32_t handle = proxy ? proxy->handle() : 0;
  189. obj.type = BINDER_TYPE_WEAK_HANDLE;
  190. obj.handle = handle;
  191. obj.cookie = NULL;
  192. } else {
  193. obj.type = BINDER_TYPE_WEAK_BINDER;
  194. obj.binder = binder.get_refs();
  195. obj.cookie = binder.unsafe_get();
  196. }
  197. return finish_flatten_binder(real, obj, out);
  198. }
复制代码java代码:
  1. // XXX How to deal? In order to flatten the given binder,
  2. // we need to probe it for information, which requires a primary
  3. // reference… but we don’t have one.
  4. //
  5. // The OpenBinder implementation uses a dynamic_cast<> here,
  6. // but we can’t do that with the different reference counting
  7. // implementation we are using.
  8. LOGE(“Unable to unflatten Binder weak reference!”);
  9. obj.type = BINDER_TYPE_BINDER;
  10. obj.binder = NULL;
  11. obj.cookie = NULL;
  12. return finish_flatten_binder(NULL, obj, out);

  13. } else {
  14. obj.type = BINDER_TYPE_BINDER;
  15. obj.binder = NULL;
  16. obj.cookie = NULL;
  17. return finish_flatten_binder(NULL, obj, out);
  18. }
  19. }

  20. inline static status_t finish_unflatten_binder(
  21. BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
  22. {
  23. return NO_ERROR;
  24. }

  25. status_t unflatten_binder(const sp& proc,
  26. const Parcel& in, sp* out)
  27. {
  28. const flat_binder_object* flat = in.readObject(false);

  29. if (flat) {
  30. switch (flat->type) {
  31. case BINDER_TYPE_BINDER:
  32. *out = static_cast(flat->cookie);
  33. return finish_unflatten_binder(NULL, *flat, in);
  34. case BINDER_TYPE_HANDLE:
  35. *out = proc->getStrongProxyForHandle(flat->handle);
  36. return finish_unflatten_binder(
  37. static_cast(out->get()), *flat, in);
  38. }
  39. }
  40. return BAD_TYPE;
  41. }

  42. status_t unflatten_binder(const sp& proc,
  43. const Parcel& in, wp* out)
  44. {
  45. const flat_binder_object* flat = in.readObject(false);

  46. if (flat) {
  47. switch (flat->type) {
  48. case BINDER_TYPE_BINDER:
  49. *out = static_cast(flat->cookie);
  50. return finish_unflatten_binder(NULL, *flat, in);
  51. case BINDER_TYPE_WEAK_BINDER:
  52. if (flat->binder != NULL) {
  53. out->set_object_and_refs(
  54. static_cast(flat->cookie),
  55. static_cast(flat->binder));
  56. } else {
  57. *out = NULL;
  58. }
  59. return finish_unflatten_binder(NULL, *flat, in);
  60. case BINDER_TYPE_HANDLE:
  61. case BINDER_TYPE_WEAK_HANDLE:
  62. *out = proc->getWeakProxyForHandle(flat->handle);
  63. return finish_unflatten_binder(
  64. static_cast(out->unsafe_get()), *flat, in);
  65. }
  66. }
  67. return BAD_TYPE;
  68. }

  69. // —————————————————————————

  70. Parcel::Parcel()
  71. {
  72. initState();
  73. }

  74. Parcel::~Parcel()
  75. {
  76. freeDataNoInit();
  77. }

  78. const uint8_t* Parcel::data() const
  79. {
  80. return mData;
  81. }

  82. size_t Parcel::dataSize() const
  83. {
  84. return (mDataSize > mDataPos ? mDataSize : mDataPos);
  85. }

  86. size_t Parcel::dataAvail() const
  87. {
  88. // TODO: decide what to do about the possibility that this can
  89. // report an available-data size that exceeds a Java int’s max
  90. // positive value, causing havoc. Fortunately this will only
  91. // happen if someone constructs a Parcel containing more than two
  92. // gigabytes of data, which on typical phone hardware is simply
  93. // not possible.
  94. return dataSize() – dataPosition();
  95. }

  96. size_t Parcel::dataPosition() const
  97. {
  98. return mDataPos;
  99. }

  100. size_t Parcel::dataCapacity() const
  101. {
  102. return mDataCapacity;
  103. }

  104. status_t Parcel::setDataSize(size_t size)
  105. {
  106. status_t err;
  107. err = continueWrite(size);
  108. if (err == NO_ERROR) {
  109. mDataSize = size;
  110. LOGV(“setDataSize Setting data size of %p to %d/n”, this, mDataSize);
  111. }
  112. return err;
  113. }

  114. void Parcel::setDataPosition(size_t pos) const
  115. {
  116. mDataPos = pos;
  117. mNextObjectHint = 0;
  118. }

  119. status_t Parcel::setDataCapacity(size_t size)
  120. {
  121. if (size > mDataSize) return continueWrite(size);
  122. return NO_ERROR;
  123. }

  124. status_t Parcel::setData(const uint8_t* buffer, size_t len)
  125. {
  126. status_t err = restartWrite(len);
  127. if (err == NO_ERROR) {
  128. memcpy(const_cast(data()), buffer, len);
  129. mDataSize = len;
  130. mFdsKnown = false;
  131. }
  132. return err;
  133. }

  134. status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
  135. {
  136. const sp proc(ProcessState::self());
  137. status_t err;
  138. uint8_t *data = parcel->mData;
  139. size_t *objects = parcel->mObjects;
  140. size_t size = parcel->mObjectsSize;
  141. int startPos = mDataPos;
  142. int firstIndex = -1, lastIndex = -2;

  143. if (len == 0) {
  144. return NO_ERROR;
  145. }

  146. // range checks against the source parcel size
  147. if ((offset > parcel->mDataSize)
  148. || (len > parcel->mDataSize)
  149. || (offset + len > parcel->mDataSize)) {
  150. return BAD_VALUE;
  151. }
复制代码java代码:
  1. // Count objects in range
  2. for (int i = 0; i < (int) size; i++) {
  3. size_t off = objects[i];
  4. if ((off >= offset) && (off < offset + len)) {
  5. if (firstIndex == -1) {
  6. firstIndex = i;
  7. }
  8. lastIndex = i;
  9. }
  10. }
  11. int numObjects = lastIndex - firstIndex + 1;

  12. // grow data
  13. err = growData(len);
  14. if (err != NO_ERROR) {
  15. return err;
  16. }

  17. // append data
  18. memcpy(mData + mDataPos, data + offset, len);
  19. mDataPos += len;
  20. mDataSize += len;

  21. if (numObjects > 0) {
  22. // grow objects
  23. if (mObjectsCapacity < mObjectsSize + numObjects) {
  24. int newSize = ((mObjectsSize + numObjects)*3)/2;
  25. size_t *objects =
  26. (size_t*)realloc(mObjects, newSize*sizeof(size_t));
  27. if (objects == (size_t*)0) {
  28. return NO_MEMORY;
  29. }
  30. mObjects = objects;
  31. mObjectsCapacity = newSize;
  32. }

  33. // append and acquire objects
  34. int idx = mObjectsSize;
  35. for (int i = firstIndex; i <= lastIndex; i++) {
  36. size_t off = objects[i] - offset + startPos;
  37. mObjects[idx++] = off;
  38. mObjectsSize++;

  39. flat_binder_object* flat
  40. = reinterpret_cast(mData + off);
  41. acquire_object(proc, *flat, this);

  42. if (flat->type == BINDER_TYPE_FD) {
  43. // If this is a file descriptor, we need to dup it so the
  44. // new Parcel now owns its own fd, and can declare that we
  45. // officially know we have fds.
  46. flat->handle = dup(flat->handle);
  47. flat->cookie = (void*)1;
  48. mHasFds = mFdsKnown = true;
  49. }
  50. }
  51. }

  52. return NO_ERROR;
  53. }

  54. bool Parcel::hasFileDescriptors() const
  55. {
  56. if (!mFdsKnown) {
  57. scanForFds();
  58. }
  59. return mHasFds;
  60. }

  61. status_t Parcel::writeInterfaceToken(const String16& interface)
  62. {
  63. // currently the interface identification token is just its name as a string
  64. return writeString16(interface);
  65. }

  66. bool Parcel::checkInterface(IBinder* binder) const
  67. {
  68. return enforceInterface(binder->getInterfaceDescriptor());
  69. }

  70. bool Parcel::enforceInterface(const String16& interface) const
  71. {
  72. const String16 str(readString16());
  73. if (str == interface) {
  74. return true;
  75. } else {
  76. LOGW(“**** enforceInterface() expected ‘%s’ but read ‘%s’/n”,
  77. String8(interface).string(), String8(str).string());
  78. return false;
  79. }
  80. }

  81. const size_t* Parcel::objects() const
  82. {
  83. return mObjects;
  84. }

  85. size_t Parcel::objectsCount() const
  86. {
  87. return mObjectsSize;
  88. }

  89. status_t Parcel::errorCheck() const
  90. {
  91. return mError;
  92. }

  93. void Parcel::setError(status_t err)
  94. {
  95. mError = err;
  96. }

  97. status_t Parcel::finishWrite(size_t len)
  98. {
  99. //printf(“Finish write of %d/n”, len);
  100. mDataPos += len;
  101. LOGV(“finishWrite Setting data pos of %p to %d/n”, this, mDataPos);
  102. if (mDataPos > mDataSize) {
  103. mDataSize = mDataPos;
  104. LOGV(“finishWrite Setting data size of %p to %d/n”, this, mDataSize);
  105. }
  106. //printf(“New pos=%d, size=%d/n”, mDataPos, mDataSize);
  107. return NO_ERROR;
  108. }

  109. status_t Parcel::writeUnpadded(const void* data, size_t len)
  110. {
  111. size_t end = mDataPos + len;
  112. if (end < mDataPos) {
  113. // integer overflow
  114. return BAD_VALUE;
  115. }
  116. if (end <= mDataCapacity) {
  117. restart_write:
  118. memcpy(mData+mDataPos, data, len);
  119. return finishWrite(len);
  120. }
  121. status_t err = growData(len);
  122. if (err == NO_ERROR) goto restart_write;
  123. return err;
  124. }
  125. status_t Parcel::write(const void* data, size_t len)
  126. {
  127. void* const d = writeInplace(len);
  128. if (d) {
  129. memcpy(d, data, len);
  130. return NO_ERROR;
  131. }
  132. return mError;
  133. }
  134. void* Parcel::writeInplace(size_t len)
  135. {
  136. const size_t padded = PAD_SIZE(len);
  137. // sanity check for integer overflow
  138. if (mDataPos+padded < mDataPos) {
  139. return NULL;
  140. }
  141. if ((mDataPos+padded) <= mDataCapacity) {
  142. restart_write:
  143. //printf("Writing %ld bytes, padded to %ld/n", len, padded);
  144. uint8_t* const data = mData+mDataPos;
  145. // Need to pad at end?
  146. if (padded != len) {
  147. #if BYTE_ORDER == BIG_ENDIAN
  148. static const uint32_t mask[4] = {
  149. 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
  150. };
  151. #endif
  152. #if BYTE_ORDER == LITTLE_ENDIAN
  153. static const uint32_t mask[4] = {
  154. 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
  155. };
  156. #endif
  157. //printf("Applying pad mask: %p to %p/n", (void*)mask[padded-len],
  158. // *reinterpret_cast(data+padded-4));
  159. *reinterpret_cast(data+padded-4) &= mask[padded-len];
  160. }
复制代码java代码:
  1. finishWrite(padded);
  2. return data;
  3. }

  4. status_t err = growData(padded);
  5. if (err == NO_ERROR) goto restart_write;
  6. return NULL;
  7. }

  8. status_t Parcel::writeInt32(int32_t val)
  9. {
  10. return writeAligned(val);
  11. }

  12. status_t Parcel::writeInt64(int64_t val)
  13. {
  14. return writeAligned(val);
  15. }

  16. status_t Parcel::writeFloat(float val)
  17. {
  18. return writeAligned(val);
  19. }

  20. status_t Parcel::writeDouble(double val)
  21. {
  22. return writeAligned(val);
  23. }

  24. status_t Parcel::writeIntPtr(intptr_t val)
  25. {
  26. return writeAligned(val);
  27. }

  28. status_t Parcel::writeCString(const char* str)
  29. {
  30. return write(str, strlen(str)+1);
  31. }

  32. status_t Parcel::writeString8(const String8& str)
  33. {
  34. status_t err = writeInt32(str.bytes());
  35. if (err == NO_ERROR) {
  36. err = write(str.string(), str.bytes()+1);
  37. }
  38. return err;
  39. }

  40. status_t Parcel::writeString16(const String16& str)
  41. {
  42. return writeString16(str.string(), str.size());
  43. }

  44. status_t Parcel::writeString16(const char16_t* str, size_t len)
  45. {
  46. if (str == NULL) return writeInt32(-1);

  47. status_t err = writeInt32(len);
  48. if (err == NO_ERROR) {
  49. len *= sizeof(char16_t);
  50. uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
  51. if (data) {
  52. memcpy(data, str, len);
  53. *reinterpret_cast(data+len) = 0;
  54. return NO_ERROR;
  55. }
  56. err = mError;
  57. }
  58. return err;
  59. }

  60. status_t Parcel::writeStrongBinder(const sp& val)
  61. {
  62. return flatten_binder(ProcessState::self(), val, this);
  63. }

  64. status_t Parcel::writeWeakBinder(const wp& val)
  65. {
  66. return flatten_binder(ProcessState::self(), val, this);
  67. }

  68. status_t Parcel::writeNativeHandle(const native_handle* handle)
  69. {
  70. if (!handle || handle->version != sizeof(native_handle))
  71. return BAD_TYPE;

  72. status_t err;
  73. err = writeInt32(handle->numFds);
  74. if (err != NO_ERROR) return err;

  75. err = writeInt32(handle->numInts);
  76. if (err != NO_ERROR) return err;

  77. for (int i=0 ; err==NO_ERROR && inumFds ; i++)
  78. err = writeDupFileDescriptor(handle->data[i]);

  79. if (err != NO_ERROR) {
  80. LOGD(“write native handle, write dup fd failed”);
  81. return err;
  82. }
  83. err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
  84. return err;
  85. }

  86. status_t Parcel::writeFileDescriptor(int fd)
  87. {
  88. flat_binder_object obj;
  89. obj.type = BINDER_TYPE_FD;
  90. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  91. obj.handle = fd;
  92. obj.cookie = (void*)0;
  93. return writeObject(obj, true);
  94. }

  95. status_t Parcel::writeDupFileDescriptor(int fd)
  96. {
  97. flat_binder_object obj;
  98. obj.type = BINDER_TYPE_FD;
  99. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  100. obj.handle = dup(fd);
  101. obj.cookie = (void*)1;
  102. return writeObject(obj, true);
  103. }

  104. status_t Parcel::write(const Flattenable& val)
  105. {
  106. status_t err;

  107. // size if needed
  108. size_t len = val.getFlattenedSize();
  109. size_t fd_count = val.getFdCount();

  110. err = this->writeInt32(len);
  111. if (err) return err;

  112. err = this->writeInt32(fd_count);
  113. if (err) return err;

  114. // payload
  115. void* buf = this->writeInplace(PAD_SIZE(len));
  116. if (buf == NULL)
  117. return BAD_VALUE;

  118. int* fds = NULL;
  119. if (fd_count) {
  120. fds = new int[fd_count];
  121. }

  122. err = val.flatten(buf, len, fds, fd_count);
  123. for (size_t i=0 ; i err = this->writeDupFileDescriptor( fds[i] );
  124. }

  125. if (fd_count) {
  126. delete [] fds;
  127. }

  128. return err;
  129. }

  130. status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
  131. {
  132. const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
  133. const bool enoughObjects = mObjectsSize < mObjectsCapacity;
  134. if (enoughData && enoughObjects) {
  135. restart_write:
  136. *reinterpret_cast(mData+mDataPos) = val;

  137. // Need to write meta-data?
  138. if (nullMetaData || val.binder != NULL) {
  139. mObjects[mObjectsSize] = mDataPos;
  140. acquire_object(ProcessState::self(), val, this);
  141. mObjectsSize++;
  142. }

  143. // remember if it’s a file descriptor
  144. if (val.type == BINDER_TYPE_FD) {
  145. mHasFds = mFdsKnown = true;
  146. }

  147. return finishWrite(sizeof(flat_binder_object));
  148. }

  149. if (!enoughData) {
  150. const status_t err = growData(sizeof(val));
  151. if (err != NO_ERROR) return err;
  152. }
  153. if (!enoughObjects) {
  154. size_t newSize = ((mObjectsSize+2)*3)/2;
  155. size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
  156. if (objects == NULL) return NO_MEMORY;
  157. mObjects = objects;
  158. mObjectsCapacity = newSize;
  159. }
复制代码

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)重学系列 有趣的工具--智能指针与智能锁
  3. 整理的收集的Android的学习资料(大佬们的博客,学习思路,行业要求,免
  4. android 混淆规则详解
  5. 【构建Android缓存模块】(一)吐槽与原理分析
  6. Android(安卓)代码开发工作流
  7. Android(安卓)view实例化
  8. Android(安卓)NDK之旅-OpenGL 初探
  9. git下载Android源代码(含kernel)(zz)

随机推荐

  1. Android事件分发
  2. 关于android:layout_weight属性使用注意
  3. Android开发5——文件读写
  4. Android(安卓)M新控件之FloatingActionBu
  5. Android中的Activity
  6. 键盘设备三星在Android上的改进对Develop
  7. Android(安卓)使用ORMLite打造万能泛型Da
  8. 关键(一): android不同机型的适配的解决方
  9. Android工具箱APP源码分享:“一个工具箱”
  10. android:exported 属性详解