员工年度工作总结报告(2012年度)--张宝华

   一.先从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. static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
  11. {
  12. Parcel* parcel = parcelForJavaObject(env, clazz);
  13. if (parcel != NULL) {
  14. const status_t err = parcel->writeInt64(val);
  15. if (err != NO_ERROR) {
  16. jniThrowException(env, “java/lang/OutOfMemoryError”, NULL);
  17. }
  18. }


复制代码

       从这里我们可以得到的信息是函数的实现依赖于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; 

复制代码

本帖最后由 nuli 于 2011-9-14 15:15 编辑

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. }; 

复制代码
本帖最后由 nuli 于 2011-9-14 15:15 编辑

java代码:
  1. // ————————————————————————— 

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


  6. // --------------------------------------------------------------------------- 

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

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

  20. }; // namespace android 

  21. // ————————————————————————— 

  22. #endif // ANDROID_PARCEL_H 

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

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

  41. #include 
  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. #ifndef INT32_MAX
  57. #define INT32_MAX ((int32_t)(2147483647))
  58. #endif 

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

  61. // ————————————————————————— 

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

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

  70. namespace android { 

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


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


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


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


  136. inline static status_t finish_flatten_binder(
  137. const sp& binder, const flat_binder_object& flat, Parcel* out)
  138. {
  139. return out->writeObject(flat, false);


  140. status_t flatten_binder(const sp& proc,
  141. const sp& binder, Parcel* out)
  142. {
  143. flat_binder_object obj; 

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


  165. return finish_flatten_binder(binder, obj, out);


  166. status_t flatten_binder(const sp& proc,
  167. const wp& binder, Parcel* out)
  168. {
  169. flat_binder_object obj; 

  170. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  171. if (binder != NULL) {
  172. sp real = binder.promote();
  173. if (real != NULL) {
  174. IBinder *local = real->localBinder();
  175. if (!local) {
  176. BpBinder *proxy = real->remoteBinder();
  177. if (proxy == NULL) {
  178. LOGE(“null proxy”);
  179. }
  180. const int32_t handle = proxy ? proxy->handle() : 0;
  181. obj.type = BINDER_TYPE_WEAK_HANDLE;
  182. obj.handle = handle;
  183. obj.cookie = NULL;
  184. } else {
  185. obj.type = BINDER_TYPE_WEAK_BINDER;
  186. obj.binder = binder.get_refs();
  187. obj.cookie = binder.unsafe_get();
  188. }
  189. return finish_flatten_binder(real, obj, out);


复制代码
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. inline static status_t finish_unflatten_binder(
  20. BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
  21. {
  22. return NO_ERROR;


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

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


  39. status_t unflatten_binder(const sp& proc,
  40. const Parcel& in, wp* out)
  41. {
  42. const flat_binder_object* flat = in.readObject(false); 

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


  65. // ————————————————————————— 

  66. Parcel::Parcel()
  67. {
  68. initState();


  69. Parcel::~Parcel()
  70. {
  71. freeDataNoInit();


  72. const uint8_t* Parcel::data() const
  73. {
  74. return mData;


  75. size_t Parcel::dataSize() const
  76. {
  77. return (mDataSize > mDataPos ? mDataSize : mDataPos);


  78. size_t Parcel::dataAvail() const
  79. {
  80. // TODO: decide what to do about the possibility that this can
  81. // report an available-data size that exceeds a Java int’s max
  82. // positive value, causing havoc. Fortunately this will only
  83. // happen if someone constructs a Parcel containing more than two
  84. // gigabytes of data, which on typical phone hardware is simply
  85. // not possible.
  86. return dataSize() – dataPosition();


  87. size_t Parcel::dataPosition() const
  88. {
  89. return mDataPos;


  90. size_t Parcel::dataCapacity() const
  91. {
  92. return mDataCapacity;


  93. status_t Parcel::setDataSize(size_t size)
  94. {
  95. status_t err;
  96. err = continueWrite(size);
  97. if (err == NO_ERROR) {
  98. mDataSize = size;
  99. LOGV(“setDataSize Setting data size of %p to %d/n”, this, mDataSize);
  100. }
  101. return err;


  102. void Parcel::setDataPosition(size_t pos) const
  103. {
  104. mDataPos = pos;
  105. mNextObjectHint = 0;


  106. status_t Parcel::setDataCapacity(size_t size)
  107. {
  108. if (size > mDataSize) return continueWrite(size);
  109. return NO_ERROR;


  110. status_t Parcel::setData(const uint8_t* buffer, size_t len)
  111. {
  112. status_t err = restartWrite(len);
  113. if (err == NO_ERROR) {
  114. memcpy(const_cast(data()), buffer, len);
  115. mDataSize = len;
  116. mFdsKnown = false;
  117. }
  118. return err;


  119. status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
  120. {
  121. const sp proc(ProcessState::self());
  122. status_t err;
  123. uint8_t *data = parcel->mData;
  124. size_t *objects = parcel->mObjects;
  125. size_t size = parcel->mObjectsSize;
  126. int startPos = mDataPos;
  127. int firstIndex = -1, lastIndex = -2; 

  128. if (len == 0) {
  129. return NO_ERROR;


  130. // range checks against the source parcel size
  131. if ((offset > parcel->mDataSize)
  132. || (len > parcel->mDataSize)
  133. || (offset + len > parcel->mDataSize)) {
  134. return BAD_VALUE;


复制代码
本帖最后由 nuli 于 2011-9-14 15:13 编辑

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. // append data
  17. memcpy(mData + mDataPos, data + offset, len);
  18. mDataPos += len;
  19. mDataSize += len; 

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


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

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

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


  49. return NO_ERROR;


  50. bool Parcel::hasFileDescriptors() const
  51. {
  52. if (!mFdsKnown) {
  53. scanForFds();
  54. }
  55. return mHasFds;


  56. status_t Parcel::writeInterfaceToken(const String16& interface)
  57. {
  58. // currently the interface identification token is just its name as a string
  59. return writeString16(interface);


  60. bool Parcel::checkInterface(IBinder* binder) const
  61. {
  62. return enforceInterface(binder->getInterfaceDescriptor());


  63. bool Parcel::enforceInterface(const String16& interface) const
  64. {
  65. const String16 str(readString16());
  66. if (str == interface) {
  67. return true;
  68. } else {
  69. LOGW(“**** enforceInterface() expected ‘%s’ but read ‘%s’/n”,
  70. String8(interface).string(), String8(str).string());
  71. return false;
  72. }


  73. const size_t* Parcel::objects() const
  74. {
  75. return mObjects;


  76. size_t Parcel::objectsCount() const
  77. {
  78. return mObjectsSize;


  79. status_t Parcel::errorCheck() const
  80. {
  81. return mError;


  82. void Parcel::setError(status_t err)
  83. {
  84. mError = err;


  85. status_t Parcel::finishWrite(size_t len)
  86. {
  87. //printf(“Finish write of %d/n”, len);
  88. mDataPos += len;
  89. LOGV(“finishWrite Setting data pos of %p to %d/n”, this, mDataPos);
  90. if (mDataPos > mDataSize) {
  91. mDataSize = mDataPos;
  92. LOGV(“finishWrite Setting data size of %p to %d/n”, this, mDataSize);
  93. }
  94. //printf(“New pos=%d, size=%d/n”, mDataPos, mDataSize);
  95. return NO_ERROR;


  96. status_t Parcel::writeUnpadded(const void* data, size_t len)
  97. {
  98. size_t end = mDataPos + len;
  99. if (end < mDataPos) {
  100. // integer overflow
  101. return BAD_VALUE;

  102. if (end <= mDataCapacity) {
  103. restart_write:
  104. memcpy(mData+mDataPos, data, len);
  105. return finishWrite(len);

  106. status_t err = growData(len);
  107. if (err == NO_ERROR) goto restart_write;
  108. return err;

  109. status_t Parcel::write(const void* data, size_t len)
  110. {
  111. void* const d = writeInplace(len);
  112. if (d) {
  113. memcpy(d, data, len);
  114. return NO_ERROR;
  115. }
  116. return mError;

  117. void* Parcel::writeInplace(size_t len)
  118. {
  119. const size_t padded = PAD_SIZE(len); 
  120. // sanity check for integer overflow
  121. if (mDataPos+padded < mDataPos) {
  122. return NULL;

  123. if ((mDataPos+padded) <= mDataCapacity) {
  124. restart_write:
  125. //printf("Writing %ld bytes, padded to %ld/n", len, padded);
  126. uint8_t* const data = mData+mDataPos; 
  127. // Need to pad at end?
  128. if (padded != len) {
  129. #if BYTE_ORDER == BIG_ENDIAN
  130. static const uint32_t mask[4] = {
  131. 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
  132. };
  133. #endif
  134. #if BYTE_ORDER == LITTLE_ENDIAN
  135. static const uint32_t mask[4] = {
  136. 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
  137. };
  138. #endif
  139. //printf("Applying pad mask: %p to %p/n", (void*)mask[padded-len],
  140. // *reinterpret_cast(data+padded-4));
  141. *reinterpret_cast(data+padded-4) &= mask[padded-len];

复制代码
本帖最后由 nuli 于 2011-9-14 15:14 编辑

java代码:
  1. finishWrite(padded);
  2. return data;


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


  6. status_t Parcel::writeInt32(int32_t val)
  7. {
  8. return writeAligned(val);


  9. status_t Parcel::writeInt64(int64_t val)
  10. {
  11. return writeAligned(val);


  12. status_t Parcel::writeFloat(float val)
  13. {
  14. return writeAligned(val);


  15. status_t Parcel::writeDouble(double val)
  16. {
  17. return writeAligned(val);


  18. status_t Parcel::writeIntPtr(intptr_t val)
  19. {
  20. return writeAligned(val);


  21. status_t Parcel::writeCString(const char* str)
  22. {
  23. return write(str, strlen(str)+1);


  24. status_t Parcel::writeString8(const String8& str)
  25. {
  26. status_t err = writeInt32(str.bytes());
  27. if (err == NO_ERROR) {
  28. err = write(str.string(), str.bytes()+1);
  29. }
  30. return err;


  31. status_t Parcel::writeString16(const String16& str)
  32. {
  33. return writeString16(str.string(), str.size());


  34. status_t Parcel::writeString16(const char16_t* str, size_t len)
  35. {
  36. if (str == NULL) return writeInt32(-1); 

  37. status_t err = writeInt32(len);
  38. if (err == NO_ERROR) {
  39. len *= sizeof(char16_t);
  40. uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
  41. if (data) {
  42. memcpy(data, str, len);
  43. *reinterpret_cast(data+len) = 0;
  44. return NO_ERROR;
  45. }
  46. err = mError;
  47. }
  48. return err;


  49. status_t Parcel::writeStrongBinder(const sp& val)
  50. {
  51. return flatten_binder(ProcessState::self(), val, this);


  52. status_t Parcel::writeWeakBinder(const wp& val)
  53. {
  54. return flatten_binder(ProcessState::self(), val, this);


  55. status_t Parcel::writeNativeHandle(const native_handle* handle)
  56. {
  57. if (!handle || handle->version != sizeof(native_handle))
  58. return BAD_TYPE; 

  59. status_t err;
  60. err = writeInt32(handle->numFds);
  61. if (err != NO_ERROR) return err; 

  62. err = writeInt32(handle->numInts);
  63. if (err != NO_ERROR) return err; 

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

  66. if (err != NO_ERROR) {
  67. LOGD(“write native handle, write dup fd failed”);
  68. return err;
  69. }
  70. err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
  71. return err;


  72. status_t Parcel::writeFileDescriptor(int fd)
  73. {
  74. flat_binder_object obj;
  75. obj.type = BINDER_TYPE_FD;
  76. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  77. obj.handle = fd;
  78. obj.cookie = (void*)0;
  79. return writeObject(obj, true);


  80. status_t Parcel::writeDupFileDescriptor(int fd)
  81. {
  82. flat_binder_object obj;
  83. obj.type = BINDER_TYPE_FD;
  84. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  85. obj.handle = dup(fd);
  86. obj.cookie = (void*)1;
  87. return writeObject(obj, true);


  88. status_t Parcel::write(const Flattenable& val)
  89. {
  90. status_t err; 

  91. // size if needed
  92. size_t len = val.getFlattenedSize();
  93. size_t fd_count = val.getFdCount(); 

  94. err = this->writeInt32(len);
  95. if (err) return err; 

  96. err = this->writeInt32(fd_count);
  97. if (err) return err; 

  98. // payload
  99. void* buf = this->writeInplace(PAD_SIZE(len));
  100. if (buf == NULL)
  101. return BAD_VALUE; 

  102. int* fds = NULL;
  103. if (fd_count) {
  104. fds = new int[fd_count];


  105. err = val.flatten(buf, len, fds, fd_count);
  106. for (size_t i=0 ; i err = this->writeDupFileDescriptor( fds[i] );


  107. if (fd_count) {
  108. delete [] fds;


  109. return err;


  110. status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
  111. {
  112. const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
  113. const bool enoughObjects = mObjectsSize < mObjectsCapacity;
  114. if (enoughData && enoughObjects) {
  115. restart_write:
  116. *reinterpret_cast(mData+mDataPos) = val; 

  117. // Need to write meta-data?
  118. if (nullMetaData || val.binder != NULL) {
  119. mObjects[mObjectsSize] = mDataPos;
  120. acquire_object(ProcessState::self(), val, this);
  121. mObjectsSize++;


  122. // remember if it’s a file descriptor
  123. if (val.type == BINDER_TYPE_FD) {
  124. mHasFds = mFdsKnown = true;


  125. return finishWrite(sizeof(flat_binder_object));


  126. if (!enoughData) {
  127. const status_t err = growData(sizeof(val));
  128. if (err != NO_ERROR) return err;
  129. }
  130. if (!enoughObjects) {
  131. size_t newSize = ((mObjectsSize+2)*3)/2;
  132. size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
  133. if (objects == NULL) return NO_MEMORY;
  134. mObjects = objects;
  135. mObjectsCapacity = newSize;


复制代码

猜你喜欢

转载自huaonline.iteye.com/blog/1755011
今日推荐