Parcel
- Words with same meaning:
package,bunch,bundle,pack,packet, make into a wrapped container,a wrapped container, a collection of things wrapped or boxed together
- The implementation of Parcel, write or read data from data memory
Parcel.cpp
- The header of Parcel

1 #ifndef ANDROID_PARCEL_H 2 #define ANDROID_PARCEL_H 3 #include <cutils/native_handle.h> 4 #include <utils/Errors.h> 5 #include <utils/RefBase.h> 6 #include <utils/String16.h> 7 #include <utils/Vector.h> 8 9 namespace android { 10 11 class Flattenable; 12 class IBinder; 13 class IPCThreadState; 14 class ProcessState; 15 class String8; 16 class TextOutput; 17 18 struct flat_binder_object; // defined in support_p/binder_module.h 19 class Parcel 20 { 21 public: 22 class ReadableBlob; 23 class WritableBlob; 24 Parcel(); 25 ~Parcel(); 26 const uint8_t* data() const; 27 size_t dataSize() const; 28 size_t dataAvail() const; 29 size_t dataPosition() const; 30 size_t dataCapacity() const; 31 status_t setDataSize(size_t size); 32 void setDataPosition(size_t pos) const; 33 status_t setDataCapacity(size_t size); 34 status_t setData(const uint8_t* buffer, size_t len); 35 status_t appendFrom(const Parcel *parcel,size_t start, size_t len); 36 bool pushAllowFds(bool allowFds); 37 void restoreAllowFds(bool lastValue); 38 bool hasFileDescriptors() const; 39 status_t writeInterfaceToken(const String16& interface); 40 bool enforceInterface(const String16& interface,IPCThreadState* threadState = NULL) const; 41 bool checkInterface(IBinder*) const; 42 void freeData(); 43 const size_t* objects() const; 44 size_t objectsCount() const; 45 status_t errorCheck() const; 46 void setError(status_t err); 47 status_t write(const void* data, size_t len); 48 void* writeInplace(size_t len); 49 status_t writeUnpadded(const void* data, size_t len); 50 status_t writeInt32(int32_t val); 51 status_t writeInt64(int64_t val); 52 status_t writeFloat(float val); 53 status_t writeDouble(double val); 54 status_t writeIntPtr(intptr_t val); 55 status_t writeCString(const char* str); 56 status_t writeString8(const String8& str); 57 status_t writeString16(const String16& str); 58 status_t writeString16(const char16_t* str, size_t len); 59 status_t writeStrongBinder(const sp<IBinder>& val); 60 status_t writeWeakBinder(const wp<IBinder>& val); 61 status_t write(const Flattenable& val); 62 status_t writeNativeHandle(const native_handle* handle); 63 status_t writeFileDescriptor(int fd, bool takeOwnership = false); 64 status_t writeDupFileDescriptor(int fd); 65 status_t writeBlob(size_t len, WritableBlob* outBlob); 66 status_t writeObject(const flat_binder_object& val, bool nullMetaData); 67 status_t writeNoException(); 68 void remove(size_t start, size_t amt); 69 status_t read(void* outData, size_t len) const; 70 const void* readInplace(size_t len) const; 71 int32_t readInt32() const; 72 status_t readInt32(int32_t *pArg) const; 73 int64_t readInt64() const; 74 status_t readInt64(int64_t *pArg) const; 75 float readFloat() const; 76 status_t readFloat(float *pArg) const; 77 double readDouble() const; 78 status_t readDouble(double *pArg) const; 79 intptr_t readIntPtr() const; 80 status_t readIntPtr(intptr_t *pArg) const; 81 const char* readCString() const; 82 String8 readString8() const; 83 String16 readString16() const; 84 const char16_t* readString16Inplace(size_t* outLen) const; 85 sp<IBinder> readStrongBinder() const; 86 wp<IBinder> readWeakBinder() const; 87 status_t read(Flattenable& val) const; 88 int32_t readExceptionCode() const; 89 native_handle* readNativeHandle() const; 90 int readFileDescriptor() const; 91 status_t readBlob(size_t len, ReadableBlob* outBlob) const; 92 const flat_binder_object* readObject(bool nullMetaData) const; 93 void closeFileDescriptors(); 94 typedef void (*release_func)(Parcel* parcel, 95 const uint8_t* data, size_t dataSize, 96 const size_t* objects, size_t objectsSize, 97 void* cookie); 98 const uint8_t* ipcData() const; 99 size_t ipcDataSize() const; 100 const size_t* ipcObjects() const; 101 size_t ipcObjectsCount() const; 102 void ipcSetDataReference(const uint8_t* data, size_t dataSize, 103 const size_t* objects, size_t objectsCount, 104 release_func relFunc, void* relCookie); 105 void print(TextOutput& to, uint32_t flags = 0) const; 106 private: 107 Parcel(const Parcel& o); 108 Parcel& operator=(const Parcel& o); 109 status_t finishWrite(size_t len); 110 void releaseObjects(); 111 void acquireObjects(); 112 status_t growData(size_t len); 113 status_t restartWrite(size_t desired); 114 status_t continueWrite(size_t desired); 115 void freeDataNoInit(); 116 void initState(); 117 void scanForFds() const; 118 template<class T> 119 status_t readAligned(T *pArg) const; 120 template<class T> 121 T readAligned() const; 122 template<class T> 123 status_t writeAligned(T val); 124 status_t mError; 125 uint8_t* mData; 126 size_t mDataSize; 127 size_t mDataCapacity; 128 mutable size_t mDataPos; 129 size_t* mObjects; 130 size_t mObjectsSize; 131 size_t mObjectsCapacity; 132 mutable size_t mNextObjectHint; 133 mutable bool mFdsKnown; 134 mutable bool mHasFds; 135 bool mAllowFds; 136 release_func mOwner; 137 void* mOwnerCookie; 138 class Blob { 139 public: 140 Blob(); 141 ~Blob(); 142 void release(); 143 inline size_t size() const { return mSize; } 144 protected: 145 void init(bool mapped, void* data, size_t size); 146 void clear(); 147 bool mMapped; 148 void* mData; 149 size_t mSize; 150 }; 151 152 public: 153 class ReadableBlob : public Blob { 154 friend class Parcel; 155 public: 156 inline const void* data() const { return mData; } 157 }; 158 class WritableBlob : public Blob { 159 friend class Parcel; 160 public: 161 inline void* data() { return mData; } 162 }; 163 }; 164 inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel) 165 { 166 parcel.print(to); 167 return to; 168 } 169 void acquire_object(const sp<ProcessState>& proc, 170 const flat_binder_object& obj, const void* who); 171 void release_object(const sp<ProcessState>& proc, 172 const flat_binder_object& obj, const void* who); 173 void flatten_binder(const sp<ProcessState>& proc, 174 const sp<IBinder>& binder, flat_binder_object* out); 175 void flatten_binder(const sp<ProcessState>& proc, 176 const wp<IBinder>& binder, flat_binder_object* out); 177 status_t unflatten_binder(const sp<ProcessState>& proc, 178 const flat_binder_object& flat, sp<IBinder>* out); 179 status_t unflatten_binder(const sp<ProcessState>& proc, 180 const flat_binder_object& flat, wp<IBinder>* out); 181 182 }; 183 #endif // ANDROID_PARCEL_H
- Variables and nested class in Parcle class. Everytime you want a parcle object, you must new it and allocate memory for it. But many parcle can share the same memory, only one of them is owner of shared memory.
-
1 private: 2 Parcel(const Parcel& o); 3 Parcel& operator=(const Parcel& o); 4 status_t finishWrite(size_t len); //change mDataPos after writing 5 void initState(); 6 void scanForFds() const; 7 template<class T> 8 status_t readAligned(T *pArg) const; //read data from memory 9 template<class T> 10 T readAligned() const; //read object from memory 11 template<class T> 12 status_t writeAligned(T val); //write data into memory 13 uint8_t* mData; 14 size_t mDataSize; 15 size_t mDataCapacity; 16 mutable size_t mDataPos; //alway be changed after reading or writing 17 size_t* mObjects; //object pointer memeroy,store object's index by which we can get its pointer in data 18 size_t mObjectsSize; 19 size_t mObjectsCapacity; 20 mutable size_t mNextObjectHint; 21 mutable bool mFdsKnown; 22 mutable bool mHasFds; 23 bool mAllowFds; 24 release_func mOwner;//release function for memory 25 void* mOwnerCookie; 26 class Blob { 27 public: 28 Blob(); 29 ~Blob(); 30 void release(); 31 inline size_t size() const { return mSize; } 32 protected: 33 void init(bool mapped, void* data, size_t size); 34 void clear(); 35 bool mMapped; 36 void* mData; 37 size_t mSize; 38 };
-
1 typedef void (*release_func)(Parcel* parcel, 2 const uint8_t* data, size_t dataSize, 3 const size_t* objects, size_t objectsSize, 4 void* cookie);
- use nested class
-
1 public: 2 class ReadableBlob : public Blob { 3friendclass Parcel; 4 public: 5 inline const void* data() const { return mData; } 6 }; 7 class WritableBlob : public Blob { 8friend class Parcel; 9 public: 10 inline void* data() { return mData; } 11 };
- allocate memory
-
1 status_t Parcel::restartWrite(size_t desired) 2 { 3 if (mOwner) { 4 freeData(); 5 return continueWrite(desired); 6 } 7 uint8_t* data = (uint8_t*)realloc(mData, desired); //get memory on orginal address 8 if (!data && desired > mDataCapacity) { 9 mError = NO_MEMORY; 10 return NO_MEMORY; 11 } 12 releaseObjects(); //release all objects which is not building-in type by index 13 if (data) { 14 mData = data; 15 mDataCapacity = desired; 16 } 17 mDataSize = mDataPos = 0; 18 LOGV("restartWrite Setting data size of %p to %d ", this, mDataSize); 19 LOGV("restartWrite Setting data pos of %p to %d ", this, mDataPos); 20 free(mObjects);//free memory storing object index 21 mObjects = NULL; 22 mObjectsSize = mObjectsCapacity = 0; 23 mNextObjectHint = 0; 24 mHasFds = false; 25 mFdsKnown = true; 26 mAllowFds = true; 27 28 return NO_ERROR; 29 }
1 status_t Parcel::continueWrite(size_t desired) 2 { 3 // If shrinking, first adjust for any objects that appear 4 // after the new data size. 5 size_t objectsSize = mObjectsSize; 6 if (desired < mDataSize) { 7 if (desired == 0) { 8 objectsSize = 0; 9 } else { 10 while (objectsSize > 0) { 11 if (mObjects[objectsSize-1] < desired) 12 break; 13 objectsSize--; 14 } 15 } 16 } 17 if (mOwner) { 18 // If the size is going to zero, just release the owner's data. 19 if (desired == 0) { 20 freeData(); 21 return NO_ERROR; 22 } 23 // If there is a different owner, we need to take 24 // posession. 25 uint8_t* data = (uint8_t*)malloc(desired); 26 if (!data) { 27 mError = NO_MEMORY; 28 return NO_MEMORY; 29 } 30 size_t* objects = NULL; 31 32 if (objectsSize) { 33 objects = (size_t*)malloc(objectsSize*sizeof(size_t)); 34 if (!objects) { 35 mError = NO_MEMORY; 36 return NO_MEMORY; 37 } 38 39 // Little hack to only acquire references on objects 40 // we will be keeping. 41 size_t oldObjectsSize = mObjectsSize; 42 mObjectsSize = objectsSize; 43 acquireObjects(); 44 mObjectsSize = oldObjectsSize; 45 } 46 if (mData) { 47 memcpy(data, mData, mDataSize < desired ? mDataSize : desired); 48 } 49 if (objects && mObjects) { 50 memcpy(objects, mObjects, objectsSize*sizeof(size_t)); 51 } 52 //LOGI("Freeing data ref of %p (pid=%d) ", this, getpid()); 53 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); 54 mOwner = NULL; 55 mData = data; 56 mObjects = objects; 57 mDataSize = (mDataSize < desired) ? mDataSize : desired; 58 LOGV("continueWrite Setting data size of %p to %d ", this, mDataSize); 59 mDataCapacity = desired; 60 mObjectsSize = mObjectsCapacity = objectsSize; 61 mNextObjectHint = 0; 62 } else if (mData) { 63 if (objectsSize < mObjectsSize) { 64 // Need to release refs on any objects we are dropping. 65 const sp<ProcessState> proc(ProcessState::self()); 66 for (size_t i=objectsSize; i<mObjectsSize; i++) { 67 const flat_binder_object* flat 68 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]); 69 if (flat->type == BINDER_TYPE_FD) { 70 // will need to rescan because we may have lopped off the only FDs 71 mFdsKnown = false; 72 } 73 release_object(proc, *flat, this); 74 } 75 size_t* objects =(size_t*)realloc(mObjects, objectsSize*sizeof(size_t)); 76 if (objects) { 77 mObjects = objects; 78 } 79 mObjectsSize = objectsSize; 80 mNextObjectHint = 0; 81 } 82 // We own the data, so we can just do a realloc(). 83 if (desired > mDataCapacity) { 84 uint8_t* data = (uint8_t*)realloc(mData, desired); 85 if (data) { 86 mData = data; 87 mDataCapacity = desired; 88 } else if (desired > mDataCapacity) { 89 mError = NO_MEMORY; 90 return NO_MEMORY; 91 } 92 } else { 93 if (mDataSize > desired) { 94 mDataSize = desired; 95 LOGV("continueWrite Setting data size of %p to %d ", this, mDataSize); 96 } 97 if (mDataPos > desired) { 98 mDataPos = desired; 99 LOGV("continueWrite Setting data pos of %p to %d ", this, mDataPos); 100 } 101 } 102 } else { 103 // This is the first data. Easy! 104 uint8_t* data = (uint8_t*)malloc(desired); 105 if (!data) { 106 mError = NO_MEMORY; 107 return NO_MEMORY; 108 } 109 if(!(mDataCapacity == 0 && mObjects == NULL 110 && mObjectsCapacity == 0)) { 111 LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired); 112 } 113 mData = data; 114 mDataSize = mDataPos = 0; 115 LOGV("continueWrite Setting data size of %p to %d ", this, mDataSize); 116 LOGV("continueWrite Setting data pos of %p to %d ", this, mDataPos); 117 mDataCapacity = desired; 118 } 119 return NO_ERROR; 120 }
- Free memory
-
1 void Parcel::freeData() 2 { 3 freeDataNoInit();//just free data 4 initState(); 5 }
1 void Parcel::freeDataNoInit() 2 { 3 if (mOwner) { //use customerized realse function to free memory 4 //LOGI("Freeing data ref of %p (pid=%d) ", this, getpid()); 5 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); 6 } else { 7 releaseObjects(); //free object or reference count -- 8 if (mData) free(mData); //free data 9 if (mObjects) free(mObjects);//free memory which save object pointer. 10 } 11 }
1 void Parcel::releaseObjects() 2 { 3 const sp<ProcessState> proc(ProcessState::self()); 4 size_t i = mObjectsSize; 5 uint8_t* const data = mData; 6 size_t* const objects = mObjects; 7 while (i > 0) { 8 i--; 9 const flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(data+objects[i]);//get objects type and pointer 10release_object(proc, *flat, this); 11 } 12 } 13 void release_object(const sp<ProcessState>& proc,const flat_binder_object& obj, const void* who) 14 { 15 switch (obj.type) { 16 case BINDER_TYPE_BINDER: 17 if (obj.binder) { 18 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie); 19 static_cast<IBinder*>(obj.cookie)->decStrong(who);//decrease 20 } 21 return; 22 case BINDER_TYPE_WEAK_BINDER: 23 if (obj.binder) 24 static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who); 25 return; 26 case BINDER_TYPE_HANDLE: { 27 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle); 28 if (b != NULL) { 29 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get()); 30 b->decStrong(who); 31 } 32 return; 33 } 34 case BINDER_TYPE_WEAK_HANDLE: { 35 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle); 36 if (b != NULL) b.get_refs()->decWeak(who);//decrease 37 return; 38 } 39 case BINDER_TYPE_FD: { 40 if (obj.cookie != (void*)0) close(obj.handle); 41 return; 42 } 43 } 44 LOGE("Invalid object type 0x%08lx", obj.type); 45 }
-
Read data from memory
Read building-in type
-
1 template<class T> 2 T Parcel::readAligned() const { 3 T result; //for building-in type 4 if (readAligned(&result) != NO_ERROR) { 5 result = 0; 6 } 7 return result; 8 }
1 template<class T> 2 status_t Parcel::readAligned(T *pArg) const 3 { 4 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T)); 5 if ((mDataPos+sizeof(T)) <= mDataSize) { 6 const void* data = mData+mDataPos; 7 mDataPos += sizeof(T); //move backword 8 *pArg = *reinterpret_cast<const T*>(data);//get value for int,long,float,bool,double 9 return NO_ERROR; 10 } else { 11 return NOT_ENOUGH_DATA; 12 } 13 }
Read String
-
1 const char16_t* Parcel::readString16Inplace(size_t* outLen) const 2 { 3 int32_t size = readInt32();//for string.length 4 // watch for potential int overflow from size+1 5 if (size >= 0 && size < INT32_MAX) { 6 *outLen = size; 7 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t)); 8 if (str != NULL) { 9 return str; 10 } 11 } 12 *outLen = 0; 13 return NULL; 14 }
Read Object
-
1 const flat_binder_object* Parcel::readObject(bool nullMetaData) const 2 { 3 const size_t DPOS = mDataPos; 4 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) { 5 const flat_binder_object* obj = reinterpret_cast<const flat_binder_object*>(mData+DPOS); 6 mDataPos = DPOS + sizeof(flat_binder_object); 7 if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) { 8 LOGV("readObject Setting data pos of %p to %d ", this, mDataPos); 9 return obj; 10 } 11 size_t* const OBJS = mObjects; 12 const size_t N = mObjectsSize; 13 size_t opos = mNextObjectHint; 14 if (N > 0) { 15 LOGV("Parcel %p looking for obj at %d, hint=%d ", 16 this, DPOS, opos); 17 if (opos < N) { 18 while (opos < (N-1) && OBJS[opos] < DPOS) { 19 opos++; 20 } 21 } else { 22 opos = N-1; 23 } 24if (OBJS[opos] == DPOS) { 25 // Found it! 26 LOGV("Parcel found obj %d at index %d with forward search", 27 this, DPOS, opos); 28 mNextObjectHint = opos+1; 29 LOGV("readObject Setting data pos of %p to %d ", this, mDataPos); 30 return obj; 31 } 32 // Look backwards for it... 33 while (opos > 0 && OBJS[opos] > DPOS) { 34 opos--; 35 } 36 if (OBJS[opos] == DPOS) { 37 // Found it! 38 LOGV("Parcel found obj %d at index %d with backward search", 39 this, DPOS, opos); 40 mNextObjectHint = opos+1; 41 LOGV("readObject Setting data pos of %p to %d ", this, mDataPos); 42 return obj; 43 } 44 } 45 LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list", 46 this, DPOS); 47 } 48 return NULL; 49 }
- Write data into memory
building-in type
1 template<class T> 2 status_t Parcel::writeAligned(T val) 3 { 4 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T)); 5 if ((mDataPos+sizeof(val)) <= mDataCapacity) { 6 restart_write: 7 *reinterpret_cast<T*>(mData+mDataPos) = val; 8 return finishWrite(sizeof(val)); 9 } 10 11 status_t err = growData(sizeof(val)); 12 if (err == NO_ERROR) goto restart_write; 13 return err; 14 }
1 status_t Parcel::growData(size_t len) 2 { 3 size_t newSize = ((mDataSize+len)*3)/2; 4 return (newSize <= mDataSize) 5 ? (status_t) NO_MEMORY 6 : continueWrite(newSize); 7 }
1 status_t Parcel::finishWrite(size_t len) 2 { 3 //printf("Finish write of %d ", len); 4 mDataPos += len; 5 LOGV("finishWrite Setting data pos of %p to %d ", this, mDataPos); 6 if (mDataPos > mDataSize) { 7 mDataSize = mDataPos; 8 LOGV("finishWrite Setting data size of %p to %d ", this, mDataSize); 9 } 10 //printf("New pos=%d, size=%d ", mDataPos, mDataSize); 11 return NO_ERROR; 12 }
Write Object into memory
1 status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData) 2 { 3 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity; 4 const bool enoughObjects = mObjectsSize < mObjectsCapacity; 5 if (enoughData && enoughObjects) { 6 restart_write: 7 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val; 8 9 // Need to write meta-data? 10 if (nullMetaData || val.binder != NULL) { 11 mObjects[mObjectsSize] = mDataPos; 12 acquire_object(ProcessState::self(), val, this); 13 mObjectsSize++; 14 } 15 16 // remember if it's a file descriptor 17 if (val.type == BINDER_TYPE_FD) { 18 if (!mAllowFds) { 19 return FDS_NOT_ALLOWED; 20 } 21 mHasFds = mFdsKnown = true; 22 } 23 24 return finishWrite(sizeof(flat_binder_object)); 25 } 26 27 if (!enoughData) { 28 const status_t err = growData(sizeof(val)); 29 if (err != NO_ERROR) return err; 30 } 31 if (!enoughObjects) { 32 size_t newSize = ((mObjectsSize+2)*3)/2; 33 size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t)); 34 if (objects == NULL) return NO_MEMORY; 35 mObjects = objects; 36 mObjectsCapacity = newSize; 37 } 38 39 goto restart_write; 40 }
RefBase : use reference count when using strong or weak pointer to manage allocation and free of object
- RefBase.h
-
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 #define LOG_TAG "RefBase" 18 19 #include <utils/RefBase.h> 20 21 #include <utils/Atomic.h> 22 #include <utils/CallStack.h> 23 #include <utils/Log.h> 24 #include <utils/threads.h> 25 #include <utils/TextOutput.h> 26 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <typeinfo> 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <fcntl.h> 33 #include <unistd.h> 34 35 // compile with refcounting debugging enabled 36 #define DEBUG_REFS 0 37 #define DEBUG_REFS_FATAL_SANITY_CHECKS 0 38 #define DEBUG_REFS_ENABLED_BY_DEFAULT 1 39 #define DEBUG_REFS_CALLSTACK_ENABLED 1 40 41 // log all reference counting operations 42 #define PRINT_REFS 0 43 44 // --------------------------------------------------------------------------- 45 46 namespace android { 47 48 #define INITIAL_STRONG_VALUE (1<<28) 49 50 // --------------------------------------------------------------------------- 51 52 class RefBase::weakref_impl : public RefBase::weakref_type 53 { 54 public: 55 volatile int32_t mStrong; 56 volatile int32_t mWeak; 57 RefBase* const mBase; 58 volatile int32_t mFlags; 59 60 #if !DEBUG_REFS 61 62 weakref_impl(RefBase* base) 63 : mStrong(INITIAL_STRONG_VALUE) 64 , mWeak(0) 65 , mBase(base) 66 , mFlags(0) 67 { 68 } 69 70 void addStrongRef(const void* /**id*/) { } 71 void removeStrongRef(const void* /**id*/) { } 72 void renameStrongRefId(const void* /**old_id*/, const void* /**new_id*/) { } 73 void addWeakRef(const void* /**id*/) { } 74 void removeWeakRef(const void* /**id*/) { } 75 void renameWeakRefId(const void* /**old_id*/, const void* /**new_id*/) { } 76 void printRefs() const { } 77 void trackMe(bool, bool) { } 78 79 #else 80 81 weakref_impl(RefBase* base) 82 : mStrong(INITIAL_STRONG_VALUE) 83 , mWeak(0) 84 , mBase(base) 85 , mFlags(0) 86 , mStrongRefs(NULL) 87 , mWeakRefs(NULL) 88 , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) 89 , mRetain(false) 90 { 91 } 92 93 ~weakref_impl() 94 { 95 bool dumpStack = false; 96 if (!mRetain && mStrongRefs != NULL) { 97 dumpStack = true; 98 #if DEBUG_REFS_FATAL_SANITY_CHECKS 99 LOG_ALWAYS_FATAL("Strong references remain!"); 100 #else 101 LOGE("Strong references remain:"); 102 #endif 103 ref_entry* refs = mStrongRefs; 104 while (refs) { 105 char inc = refs->ref >= 0 ? '+' : '-'; 106 LOGD(" %c ID %p (ref %d):", inc, refs->id, refs->ref); 107 #if DEBUG_REFS_CALLSTACK_ENABLED 108 refs->stack.dump(); 109 #endif 110 refs = refs->next; 111 } 112 } 113 114 if (!mRetain && mWeakRefs != NULL) { 115 dumpStack = true; 116 #if DEBUG_REFS_FATAL_SANITY_CHECKS 117 LOG_ALWAYS_FATAL("Weak references remain:"); 118 #else 119 LOGE("Weak references remain!"); 120 #endif 121 ref_entry* refs = mWeakRefs; 122 while (refs) { 123 char inc = refs->ref >= 0 ? '+' : '-'; 124 LOGD(" %c ID %p (ref %d):", inc, refs->id, refs->ref); 125 #if DEBUG_REFS_CALLSTACK_ENABLED 126 refs->stack.dump(); 127 #endif 128 refs = refs->next; 129 } 130 } 131 if (dumpStack) { 132 LOGE("above errors at:"); 133 CallStack stack; 134 stack.update(); 135 stack.dump(); 136 } 137 } 138 139 void addStrongRef(const void* id) { 140 //LOGD_IF(mTrackEnabled, 141 // "addStrongRef: RefBase=%p, id=%p", mBase, id); 142 addRef(&mStrongRefs, id, mStrong); 143 } 144 145 void removeStrongRef(const void* id) { 146 //LOGD_IF(mTrackEnabled, 147 // "removeStrongRef: RefBase=%p, id=%p", mBase, id); 148 if (!mRetain) { 149 removeRef(&mStrongRefs, id); 150 } else { 151 addRef(&mStrongRefs, id, -mStrong); 152 } 153 } 154 155 void renameStrongRefId(const void* old_id, const void* new_id) { 156 //LOGD_IF(mTrackEnabled, 157 // "renameStrongRefId: RefBase=%p, oid=%p, nid=%p", 158 // mBase, old_id, new_id); 159 renameRefsId(mStrongRefs, old_id, new_id); 160 } 161 162 void addWeakRef(const void* id) { 163 addRef(&mWeakRefs, id, mWeak); 164 } 165 166 void removeWeakRef(const void* id) { 167 if (!mRetain) { 168 removeRef(&mWeakRefs, id); 169 } else { 170 addRef(&mWeakRefs, id, -mWeak); 171 } 172 } 173 174 void renameWeakRefId(const void* old_id, const void* new_id) { 175 renameRefsId(mWeakRefs, old_id, new_id); 176 } 177 178 void trackMe(bool track, bool retain) 179 { 180 mTrackEnabled = track; 181 mRetain = retain; 182 } 183 184 void printRefs() const 185 { 186 String8 text; 187 188 { 189 Mutex::Autolock _l(mMutex); 190 char buf[128]; 191 sprintf(buf, "Strong references on RefBase %p (weakref_type %p): ", mBase, this); 192 text.append(buf); 193 printRefsLocked(&text, mStrongRefs); 194 sprintf(buf, "Weak references on RefBase %p (weakref_type %p): ", mBase, this); 195 text.append(buf); 196 printRefsLocked(&text, mWeakRefs); 197 } 198 199 { 200 char name[100]; 201 snprintf(name, 100, "/data/%p.stack", this); 202 int rc = open(name, O_RDWR | O_CREAT | O_APPEND); 203 if (rc >= 0) { 204 write(rc, text.string(), text.length()); 205 close(rc); 206 LOGD("STACK TRACE for %p saved in %s", this, name); 207 } 208 else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this, 209 name, strerror(errno)); 210 } 211 } 212 213 private: 214 struct ref_entry 215 { 216 ref_entry* next; 217 const void* id; 218 #if DEBUG_REFS_CALLSTACK_ENABLED 219 CallStack stack; 220 #endif 221 int32_t ref; 222 }; 223 224 void addRef(ref_entry** refs, const void* id, int32_t mRef) 225 { 226 if (mTrackEnabled) { 227 AutoMutex _l(mMutex); 228 229 ref_entry* ref = new ref_entry; 230 // Reference count at the time of the snapshot, but before the 231 // update. Positive value means we increment, negative--we 232 // decrement the reference count. 233 ref->ref = mRef; 234 ref->id = id; 235 #if DEBUG_REFS_CALLSTACK_ENABLED 236 ref->stack.update(2); 237 #endif 238 ref->next = *refs; 239 *refs = ref; 240 } 241 } 242 243 void removeRef(ref_entry** refs, const void* id) 244 { 245 if (mTrackEnabled) { 246 AutoMutex _l(mMutex); 247 248 ref_entry* const head = *refs; 249 ref_entry* ref = head; 250 while (ref != NULL) { 251 if (ref->id == id) { 252 *refs = ref->next; 253 delete ref; 254 return; 255 } 256 refs = &ref->next; 257 ref = *refs; 258 } 259 260 #if DEBUG_REFS_FATAL_SANITY_CHECKS 261 LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p" 262 "(weakref_type %p) that doesn't exist!", 263 id, mBase, this); 264 #endif 265 266 LOGE("RefBase: removing id %p on RefBase %p" 267 "(weakref_type %p) that doesn't exist!", 268 id, mBase, this); 269 270 ref = head; 271 while (ref) { 272 char inc = ref->ref >= 0 ? '+' : '-'; 273 LOGD(" %c ID %p (ref %d):", inc, ref->id, ref->ref); 274 ref = ref->next; 275 } 276 277 CallStack stack; 278 stack.update(); 279 stack.dump(); 280 } 281 } 282 283 void renameRefsId(ref_entry* r, const void* old_id, const void* new_id) 284 { 285 if (mTrackEnabled) { 286 AutoMutex _l(mMutex); 287 ref_entry* ref = r; 288 while (ref != NULL) { 289 if (ref->id == old_id) { 290 ref->id = new_id; 291 } 292 ref = ref->next; 293 } 294 } 295 } 296 297 void printRefsLocked(String8* out, const ref_entry* refs) const 298 { 299 char buf[128]; 300 while (refs) { 301 char inc = refs->ref >= 0 ? '+' : '-'; 302 sprintf(buf, " %c ID %p (ref %d): ", 303 inc, refs->id, refs->ref); 304 out->append(buf); 305 #if DEBUG_REFS_CALLSTACK_ENABLED 306 out->append(refs->stack.toString(" ")); 307 #else 308 out->append(" (call stacks disabled)"); 309 #endif 310 refs = refs->next; 311 } 312 } 313 314 mutable Mutex mMutex; 315 ref_entry* mStrongRefs; 316 ref_entry* mWeakRefs; 317 318 bool mTrackEnabled; 319 // Collect stack traces on addref and removeref, instead of deleting the stack references 320 // on removeref that match the address ones. 321 bool mRetain; 322 323 #endif 324 }; 325 326 // --------------------------------------------------------------------------- 327 328 void RefBase::incStrong(const void* id) const 329 { 330 weakref_impl* const refs = mRefs; 331 refs->incWeak(id); 332 333 refs->addStrongRef(id); 334 const int32_t c = android_atomic_inc(&refs->mStrong); 335 LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); 336 #if PRINT_REFS 337 LOGD("incStrong of %p from %p: cnt=%d ", this, id, c); 338 #endif 339 if (c != INITIAL_STRONG_VALUE) { 340 return; 341 } 342 343 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 344 refs->mBase->onFirstRef(); 345 } 346 347 void RefBase::decStrong(const void* id) const 348 { 349 weakref_impl* const refs = mRefs; 350 refs->removeStrongRef(id); 351 const int32_t c = android_atomic_dec(&refs->mStrong); 352 #if PRINT_REFS 353 LOGD("decStrong of %p from %p: cnt=%d ", this, id, c); 354 #endif 355 LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); 356 if (c == 1) { 357 refs->mBase->onLastStrongRef(id); 358 if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { 359 delete this; 360 } 361 } 362 refs->decWeak(id); 363 } 364 365 void RefBase::forceIncStrong(const void* id) const 366 { 367 weakref_impl* const refs = mRefs; 368 refs->incWeak(id); 369 370 refs->addStrongRef(id); 371 const int32_t c = android_atomic_inc(&refs->mStrong); 372 LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", 373 refs); 374 #if PRINT_REFS 375 LOGD("forceIncStrong of %p from %p: cnt=%d ", this, id, c); 376 #endif 377 378 switch (c) { 379 case INITIAL_STRONG_VALUE: 380 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 381 // fall through... 382 case 0: 383 refs->mBase->onFirstRef(); 384 } 385 } 386 387 int32_t RefBase::getStrongCount() const 388 { 389 return mRefs->mStrong; 390 } 391 392 RefBase* RefBase::weakref_type::refBase() const 393 { 394 return static_cast<const weakref_impl*>(this)->mBase; 395 } 396 397 void RefBase::weakref_type::incWeak(const void* id) 398 { 399 weakref_impl* const impl = static_cast<weakref_impl*>(this); 400 impl->addWeakRef(id); 401 const int32_t c = android_atomic_inc(&impl->mWeak); 402 LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); 403 } 404 405 406 void RefBase::weakref_type::decWeak(const void* id) 407 { 408 weakref_impl* const impl = static_cast<weakref_impl*>(this); 409 impl->removeWeakRef(id); 410 const int32_t c = android_atomic_dec(&impl->mWeak); 411 LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); 412 if (c != 1) return; 413 414 if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { 415 // This is the regular lifetime case. The object is destroyed 416 // when the last strong reference goes away. Since weakref_impl 417 // outlive the object, it is not destroyed in the dtor, and 418 // we'll have to do it here. 419 if (impl->mStrong == INITIAL_STRONG_VALUE) { 420 // Special case: we never had a strong reference, so we need to 421 // destroy the object now. 422 delete impl->mBase; 423 } else { 424 // LOGV("Freeing refs %p of old RefBase %p ", this, impl->mBase); 425 delete impl; 426 } 427 } else { 428 // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER} 429 impl->mBase->onLastWeakRef(id); 430 if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { 431 // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference 432 // is gone, we can destroy the object. 433 delete impl->mBase; 434 } 435 } 436 } 437 438 bool RefBase::weakref_type::attemptIncStrong(const void* id) 439 { 440 incWeak(id); 441 442 weakref_impl* const impl = static_cast<weakref_impl*>(this); 443 444 int32_t curCount = impl->mStrong; 445 LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", 446 this); 447 while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { 448 if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { 449 break; 450 } 451 curCount = impl->mStrong; 452 } 453 454 if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { 455 bool allow; 456 if (curCount == INITIAL_STRONG_VALUE) { 457 // Attempting to acquire first strong reference... this is allowed 458 // if the object does NOT have a longer lifetime (meaning the 459 // implementation doesn't need to see this), or if the implementation 460 // allows it to happen. 461 allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK 462 || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 463 } else { 464 // Attempting to revive the object... this is allowed 465 // if the object DOES have a longer lifetime (so we can safely 466 // call the object with only a weak ref) and the implementation 467 // allows it to happen. 468 allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK 469 && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 470 } 471 if (!allow) { 472 decWeak(id); 473 return false; 474 } 475 curCount = android_atomic_inc(&impl->mStrong); 476 477 // If the strong reference count has already been incremented by 478 // someone else, the implementor of onIncStrongAttempted() is holding 479 // an unneeded reference. So call onLastStrongRef() here to remove it. 480 // (No, this is not pretty.) Note that we MUST NOT do this if we 481 // are in fact acquiring the first reference. 482 if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) { 483 impl->mBase->onLastStrongRef(id); 484 } 485 } 486 487 impl->addStrongRef(id); 488 489 #if PRINT_REFS 490 LOGD("attemptIncStrong of %p from %p: cnt=%d ", this, id, curCount); 491 #endif 492 493 if (curCount == INITIAL_STRONG_VALUE) { 494 android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong); 495 impl->mBase->onFirstRef(); 496 } 497 498 return true; 499 } 500 501 bool RefBase::weakref_type::attemptIncWeak(const void* id) 502 { 503 weakref_impl* const impl = static_cast<weakref_impl*>(this); 504 505 int32_t curCount = impl->mWeak; 506 LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", 507 this); 508 while (curCount > 0) { 509 if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) { 510 break; 511 } 512 curCount = impl->mWeak; 513 } 514 515 if (curCount > 0) { 516 impl->addWeakRef(id); 517 } 518 519 return curCount > 0; 520 } 521 522 int32_t RefBase::weakref_type::getWeakCount() const 523 { 524 return static_cast<const weakref_impl*>(this)->mWeak; 525 } 526 527 void RefBase::weakref_type::printRefs() const 528 { 529 static_cast<const weakref_impl*>(this)->printRefs(); 530 } 531 532 void RefBase::weakref_type::trackMe(bool enable, bool retain) 533 { 534 static_cast<weakref_impl*>(this)->trackMe(enable, retain); 535 } 536 537 RefBase::weakref_type* RefBase::createWeak(const void* id) const 538 { 539 mRefs->incWeak(id); 540 return mRefs; 541 } 542 543 RefBase::weakref_type* RefBase::getWeakRefs() const 544 { 545 return mRefs; 546 } 547 548 RefBase::RefBase() 549 : mRefs(new weakref_impl(this)) 550 { 551 } 552 553 RefBase::~RefBase() 554 { 555 if (mRefs->mStrong == INITIAL_STRONG_VALUE) { 556 // we never acquired a strong (and/or weak) reference on this object. 557 delete mRefs; 558 } else { 559 // life-time of this object is extended to WEAK or FOREVER, in 560 // which case weakref_impl doesn't out-live the object and we 561 // can free it now. 562 if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { 563 // It's possible that the weak count is not 0 if the object 564 // re-acquired a weak reference in its destructor 565 if (mRefs->mWeak == 0) { 566 delete mRefs; 567 } 568 } 569 } 570 // for debugging purposes, clear this. 571 const_cast<weakref_impl*&>(mRefs) = NULL; 572 } 573 574 void RefBase::extendObjectLifetime(int32_t mode) 575 { 576 android_atomic_or(mode, &mRefs->mFlags); 577 } 578 579 void RefBase::onFirstRef() 580 { 581 } 582 583 void RefBase::onLastStrongRef(const void* /**id*/) 584 { 585 } 586 587 bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id) 588 { 589 return (flags&FIRST_INC_STRONG) ? true : false; 590 } 591 592 void RefBase::onLastWeakRef(const void* /**id*/) 593 { 594 } 595 596 // --------------------------------------------------------------------------- 597 598 void RefBase::moveReferences(void* dst, void const* src, size_t n, 599 const ReferenceConverterBase& caster) 600 { 601 #if DEBUG_REFS 602 const size_t itemSize = caster.getReferenceTypeSize(); 603 for (size_t i=0 ; i<n ; i++) { 604 void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize); 605 void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize); 606 RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d))); 607 ref->mRefs->renameStrongRefId(s, d); 608 ref->mRefs->renameWeakRefId(s, d); 609 } 610 #endif 611 } 612 613 // --------------------------------------------------------------------------- 614 615 TextOutput& printStrongPointer(TextOutput& to, const void* val) 616 { 617 to << "sp<>(" << val << ")"; 618 return to; 619 } 620 621 TextOutput& printWeakPointer(TextOutput& to, const void* val) 622 { 623 to << "wp<>(" << val << ")"; 624 return to; 625 } 626 627 628 }; // namespace android
- RefBase.cpp
-
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 #define LOG_TAG "RefBase" 18 19 #include <utils/RefBase.h> 20 21 #include <utils/Atomic.h> 22 #include <utils/CallStack.h> 23 #include <utils/Log.h> 24 #include <utils/threads.h> 25 #include <utils/TextOutput.h> 26 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <typeinfo> 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <fcntl.h> 33 #include <unistd.h> 34 35 // compile with refcounting debugging enabled 36 #define DEBUG_REFS 0 37 #define DEBUG_REFS_FATAL_SANITY_CHECKS 0 38 #define DEBUG_REFS_ENABLED_BY_DEFAULT 1 39 #define DEBUG_REFS_CALLSTACK_ENABLED 1 40 41 // log all reference counting operations 42 #define PRINT_REFS 0 43 44 // --------------------------------------------------------------------------- 45 46 namespace android { 47 48 #define INITIAL_STRONG_VALUE (1<<28) 49 50 // --------------------------------------------------------------------------- 51 52 class RefBase::weakref_impl : public RefBase::weakref_type 53 { 54 public: 55 volatile int32_t mStrong; 56 volatile int32_t mWeak; 57 RefBase* const mBase; 58 volatile int32_t mFlags; 59 60 #if !DEBUG_REFS 61 62 weakref_impl(RefBase* base) 63 : mStrong(INITIAL_STRONG_VALUE) 64 , mWeak(0) 65 , mBase(base) 66 , mFlags(0) 67 { 68 } 69 70 void addStrongRef(const void* /**id*/) { } 71 void removeStrongRef(const void* /**id*/) { } 72 void renameStrongRefId(const void* /**old_id*/, const void* /**new_id*/) { } 73 void addWeakRef(const void* /**id*/) { } 74 void removeWeakRef(const void* /**id*/) { } 75 void renameWeakRefId(const void* /**old_id*/, const void* /**new_id*/) { } 76 void printRefs() const { } 77 void trackMe(bool, bool) { } 78 79 #else 80 81 weakref_impl(RefBase* base) 82 : mStrong(INITIAL_STRONG_VALUE) 83 , mWeak(0) 84 , mBase(base) 85 , mFlags(0) 86 , mStrongRefs(NULL) 87 , mWeakRefs(NULL) 88 , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) 89 , mRetain(false) 90 { 91 } 92 93 ~weakref_impl() 94 { 95 bool dumpStack = false; 96 if (!mRetain && mStrongRefs != NULL) { 97 dumpStack = true; 98 #if DEBUG_REFS_FATAL_SANITY_CHECKS 99 LOG_ALWAYS_FATAL("Strong references remain!"); 100 #else 101 LOGE("Strong references remain:"); 102 #endif 103 ref_entry* refs = mStrongRefs; 104 while (refs) { 105 char inc = refs->ref >= 0 ? '+' : '-'; 106 LOGD(" %c ID %p (ref %d):", inc, refs->id, refs->ref); 107 #if DEBUG_REFS_CALLSTACK_ENABLED 108 refs->stack.dump(); 109 #endif 110 refs = refs->next; 111 } 112 } 113 114 if (!mRetain && mWeakRefs != NULL) { 115 dumpStack = true; 116 #if DEBUG_REFS_FATAL_SANITY_CHECKS 117 LOG_ALWAYS_FATAL("Weak references remain:"); 118 #else 119 LOGE("Weak references remain!"); 120 #endif 121 ref_entry* refs = mWeakRefs; 122 while (refs) { 123 char inc = refs->ref >= 0 ? '+' : '-'; 124 LOGD(" %c ID %p (ref %d):", inc, refs->id, refs->ref); 125 #if DEBUG_REFS_CALLSTACK_ENABLED 126 refs->stack.dump(); 127 #endif 128 refs = refs->next; 129 } 130 } 131 if (dumpStack) { 132 LOGE("above errors at:"); 133 CallStack stack; 134 stack.update(); 135 stack.dump(); 136 } 137 } 138 139 void addStrongRef(const void* id) { 140 //LOGD_IF(mTrackEnabled, 141 // "addStrongRef: RefBase=%p, id=%p", mBase, id); 142 addRef(&mStrongRefs, id, mStrong); 143 } 144 145 void removeStrongRef(const void* id) { 146 //LOGD_IF(mTrackEnabled, 147 // "removeStrongRef: RefBase=%p, id=%p", mBase, id); 148 if (!mRetain) { 149 removeRef(&mStrongRefs, id); 150 } else { 151 addRef(&mStrongRefs, id, -mStrong); 152 } 153 } 154 155 void renameStrongRefId(const void* old_id, const void* new_id) { 156 //LOGD_IF(mTrackEnabled, 157 // "renameStrongRefId: RefBase=%p, oid=%p, nid=%p", 158 // mBase, old_id, new_id); 159 renameRefsId(mStrongRefs, old_id, new_id); 160 } 161 162 void addWeakRef(const void* id) { 163 addRef(&mWeakRefs, id, mWeak); 164 } 165 166 void removeWeakRef(const void* id) { 167 if (!mRetain) { 168 removeRef(&mWeakRefs, id); 169 } else { 170 addRef(&mWeakRefs, id, -mWeak); 171 } 172 } 173 174 void renameWeakRefId(const void* old_id, const void* new_id) { 175 renameRefsId(mWeakRefs, old_id, new_id); 176 } 177 178 void trackMe(bool track, bool retain) 179 { 180 mTrackEnabled = track; 181 mRetain = retain; 182 } 183 184 void printRefs() const 185 { 186 String8 text; 187 188 { 189 Mutex::Autolock _l(mMutex); 190 char buf[128]; 191 sprintf(buf, "Strong references on RefBase %p (weakref_type %p): ", mBase, this); 192 text.append(buf); 193 printRefsLocked(&text, mStrongRefs); 194 sprintf(buf, "Weak references on RefBase %p (weakref_type %p): ", mBase, this); 195 text.append(buf); 196 printRefsLocked(&text, mWeakRefs); 197 } 198 199 { 200 char name[100]; 201 snprintf(name, 100, "/data/%p.stack", this); 202 int rc = open(name, O_RDWR | O_CREAT | O_APPEND); 203 if (rc >= 0) { 204 write(rc, text.string(), text.length()); 205 close(rc); 206 LOGD("STACK TRACE for %p saved in %s", this, name); 207 } 208 else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this, 209 name, strerror(errno)); 210 } 211 } 212 213 private: 214 struct ref_entry 215 { 216 ref_entry* next; 217 const void* id; 218 #if DEBUG_REFS_CALLSTACK_ENABLED 219 CallStack stack; 220 #endif 221 int32_t ref; 222 }; 223 224 void addRef(ref_entry** refs, const void* id, int32_t mRef) 225 { 226 if (mTrackEnabled) { 227 AutoMutex _l(mMutex); 228 229 ref_entry* ref = new ref_entry; 230 // Reference count at the time of the snapshot, but before the 231 // update. Positive value means we increment, negative--we 232 // decrement the reference count. 233 ref->ref = mRef; 234 ref->id = id; 235 #if DEBUG_REFS_CALLSTACK_ENABLED 236 ref->stack.update(2); 237 #endif 238 ref->next = *refs; 239 *refs = ref; 240 } 241 } 242 243 void removeRef(ref_entry** refs, const void* id) 244 { 245 if (mTrackEnabled) { 246 AutoMutex _l(mMutex); 247 248 ref_entry* const head = *refs; 249 ref_entry* ref = head; 250 while (ref != NULL) { 251 if (ref->id == id) { 252 *refs = ref->next; 253 delete ref; 254 return; 255 } 256 refs = &ref->next; 257 ref = *refs; 258 } 259 260 #if DEBUG_REFS_FATAL_SANITY_CHECKS 261 LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p" 262 "(weakref_type %p) that doesn't exist!", 263 id, mBase, this); 264 #endif 265 266 LOGE("RefBase: removing id %p on RefBase %p" 267 "(weakref_type %p) that doesn't exist!", 268 id, mBase, this); 269 270 ref = head; 271 while (ref) { 272 char inc = ref->ref >= 0 ? '+' : '-'; 273 LOGD(" %c ID %p (ref %d):", inc, ref->id, ref->ref); 274 ref = ref->next; 275 } 276 277 CallStack stack; 278 stack.update(); 279 stack.dump(); 280 } 281 } 282 283 void renameRefsId(ref_entry* r, const void* old_id, const void* new_id) 284 { 285 if (mTrackEnabled) { 286 AutoMutex _l(mMutex); 287 ref_entry* ref = r; 288 while (ref != NULL) { 289 if (ref->id == old_id) { 290 ref->id = new_id; 291 } 292 ref = ref->next; 293 } 294 } 295 } 296 297 void printRefsLocked(String8* out, const ref_entry* refs) const 298 { 299 char buf[128]; 300 while (refs) { 301 char inc = refs->ref >= 0 ? '+' : '-'; 302 sprintf(buf, " %c ID %p (ref %d): ", 303 inc, refs->id, refs->ref); 304 out->append(buf); 305 #if DEBUG_REFS_CALLSTACK_ENABLED 306 out->append(refs->stack.toString(" ")); 307 #else 308 out->append(" (call stacks disabled)"); 309 #endif 310 refs = refs->next; 311 } 312 } 313 314 mutable Mutex mMutex; 315 ref_entry* mStrongRefs; 316 ref_entry* mWeakRefs; 317 318 bool mTrackEnabled; 319 // Collect stack traces on addref and removeref, instead of deleting the stack references 320 // on removeref that match the address ones. 321 bool mRetain; 322 323 #endif 324 }; 325 326 // --------------------------------------------------------------------------- 327 328 void RefBase::incStrong(const void* id) const 329 { 330 weakref_impl* const refs = mRefs; 331 refs->incWeak(id); 332 333 refs->addStrongRef(id); 334 const int32_t c = android_atomic_inc(&refs->mStrong); 335 LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); 336 #if PRINT_REFS 337 LOGD("incStrong of %p from %p: cnt=%d ", this, id, c); 338 #endif 339 if (c != INITIAL_STRONG_VALUE) { 340 return; 341 } 342 343 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 344 refs->mBase->onFirstRef(); 345 } 346 347 void RefBase::decStrong(const void* id) const 348 { 349 weakref_impl* const refs = mRefs; 350 refs->removeStrongRef(id); 351 const int32_t c = android_atomic_dec(&refs->mStrong); 352 #if PRINT_REFS 353 LOGD("decStrong of %p from %p: cnt=%d ", this, id, c); 354 #endif 355 LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); 356 if (c == 1) { 357 refs->mBase->onLastStrongRef(id); 358 if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { 359 delete this; 360 } 361 } 362 refs->decWeak(id); 363 } 364 365 void RefBase::forceIncStrong(const void* id) const 366 { 367 weakref_impl* const refs = mRefs; 368 refs->incWeak(id); 369 370 refs->addStrongRef(id); 371 const int32_t c = android_atomic_inc(&refs->mStrong); 372 LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", 373 refs); 374 #if PRINT_REFS 375 LOGD("forceIncStrong of %p from %p: cnt=%d ", this, id, c); 376 #endif 377 378 switch (c) { 379 case INITIAL_STRONG_VALUE: 380 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 381 // fall through... 382 case 0: 383 refs->mBase->onFirstRef(); 384 } 385 } 386 387 int32_t RefBase::getStrongCount() const 388 { 389 return mRefs->mStrong; 390 } 391 392 RefBase* RefBase::weakref_type::refBase() const 393 { 394 return static_cast<const weakref_impl*>(this)->mBase; 395 } 396 397 void RefBase::weakref_type::incWeak(const void* id) 398 { 399 weakref_impl* const impl = static_cast<weakref_impl*>(this); 400 impl->addWeakRef(id); 401 const int32_t c = android_atomic_inc(&impl->mWeak); 402 LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); 403 } 404 405 406 void RefBase::weakref_type::decWeak(const void* id) 407 { 408 weakref_impl* const impl = static_cast<weakref_impl*>(this); 409 impl->removeWeakRef(id); 410 const int32_t c = android_atomic_dec(&impl->mWeak); 411 LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); 412 if (c != 1) return; 413 414 if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { 415 // This is the regular lifetime case. The object is destroyed 416 // when the last strong reference goes away. Since weakref_impl 417 // outlive the object, it is not destroyed in the dtor, and 418 // we'll have to do it here. 419 if (impl->mStrong == INITIAL_STRONG_VALUE) { 420 // Special case: we never had a strong reference, so we need to 421 // destroy the object now. 422 delete impl->mBase; 423 } else { 424 // LOGV("Freeing refs %p of old RefBase %p ", this, impl->mBase); 425 delete impl; 426 } 427 } else { 428 // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER} 429 impl->mBase->onLastWeakRef(id); 430 if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { 431 // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference 432 // is gone, we can destroy the object. 433 delete impl->mBase; 434 } 435 } 436 } 437 438 bool RefBase::weakref_type::attemptIncStrong(const void* id) 439 { 440 incWeak(id); 441 442 weakref_impl* const impl = static_cast<weakref_impl*>(this); 443 444 int32_t curCount = impl->mStrong; 445 LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", 446 this); 447 while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { 448 if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { 449 break; 450 } 451 curCount = impl->mStrong; 452 } 453 454 if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { 455 bool allow; 456 if (curCount == INITIAL_STRONG_VALUE) { 457 // Attempting to acquire first strong reference... this is allowed 458 // if the object does NOT have a longer lifetime (meaning the 459 // implementation doesn't need to see this), or if the implementation 460 // allows it to happen. 461 allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK 462 || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 463 } else { 464 // Attempting to revive the object... this is allowed 465 // if the object DOES have a longer lifetime (so we can safely 466 // call the object with only a weak ref) and the implementation 467 // allows it to happen. 468 allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK 469 && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 470 } 471 if (!allow) { 472 decWeak(id); 473 return false; 474 } 475 curCount = android_atomic_inc(&impl->mStrong); 476 477 // If the strong reference count has already been incremented by 478 // someone else, the implementor of onIncStrongAttempted() is holding 479 // an unneeded reference. So call onLastStrongRef() here to remove it. 480 // (No, this is not pretty.) Note that we MUST NOT do this if we 481 // are in fact acquiring the first reference. 482 if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) { 483 impl->mBase->onLastStrongRef(id); 484 } 485 } 486 487 impl->addStrongRef(id); 488 489 #if PRINT_REFS 490 LOGD("attemptIncStrong of %p from %p: cnt=%d ", this, id, curCount); 491 #endif 492 493 if (curCount == INITIAL_STRONG_VALUE) { 494 android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong); 495 impl->mBase->onFirstRef(); 496 } 497 498 return true; 499 } 500 501 bool RefBase::weakref_type::attemptIncWeak(const void* id) 502 { 503 weakref_impl* const impl = static_cast<weakref_impl*>(this); 504 505 int32_t curCount = impl->mWeak; 506 LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", 507 this); 508 while (curCount > 0) { 509 if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) { 510 break; 511 } 512 curCount = impl->mWeak; 513 } 514 515 if (curCount > 0) { 516 impl->addWeakRef(id); 517 } 518 519 return curCount > 0; 520 } 521 522 int32_t RefBase::weakref_type::getWeakCount() const 523 { 524 return static_cast<const weakref_impl*>(this)->mWeak; 525 } 526 527 void RefBase::weakref_type::printRefs() const 528 { 529 static_cast<const weakref_impl*>(this)->printRefs(); 530 } 531 532 void RefBase::weakref_type::trackMe(bool enable, bool retain) 533 { 534 static_cast<weakref_impl*>(this)->trackMe(enable, retain); 535 } 536 537 RefBase::weakref_type* RefBase::createWeak(const void* id) const 538 { 539 mRefs->incWeak(id); 540 return mRefs; 541 } 542 543 RefBase::weakref_type* RefBase::getWeakRefs() const 544 { 545 return mRefs; 546 } 547 548 RefBase::RefBase() 549 : mRefs(new weakref_impl(this)) 550 { 551 } 552 553 RefBase::~RefBase() 554 { 555 if (mRefs->mStrong == INITIAL_STRONG_VALUE) { 556 // we never acquired a strong (and/or weak) reference on this object. 557 delete mRefs; 558 } else { 559 // life-time of this object is extended to WEAK or FOREVER, in 560 // which case weakref_impl doesn't out-live the object and we 561 // can free it now. 562 if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { 563 // It's possible that the weak count is not 0 if the object 564 // re-acquired a weak reference in its destructor 565 if (mRefs->mWeak == 0) { 566 delete mRefs; 567 } 568 } 569 } 570 // for debugging purposes, clear this. 571 const_cast<weakref_impl*&>(mRefs) = NULL; 572 } 573 574 void RefBase::extendObjectLifetime(int32_t mode) 575 { 576 android_atomic_or(mode, &mRefs->mFlags); 577 } 578 579 void RefBase::onFirstRef() 580 { 581 } 582 583 void RefBase::onLastStrongRef(const void* /**id*/) 584 { 585 } 586 587 bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id) 588 { 589 return (flags&FIRST_INC_STRONG) ? true : false; 590 } 591 592 void RefBase::onLastWeakRef(const void* /**id*/) 593 { 594 } 595 596 // --------------------------------------------------------------------------- 597 598 void RefBase::moveReferences(void* dst, void const* src, size_t n, 599 const ReferenceConverterBase& caster) 600 { 601 #if DEBUG_REFS 602 const size_t itemSize = caster.getReferenceTypeSize(); 603 for (size_t i=0 ; i<n ; i++) { 604 void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize); 605 void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize); 606 RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d))); 607 ref->mRefs->renameStrongRefId(s, d); 608 ref->mRefs->renameWeakRefId(s, d); 609 } 610 #endif 611 } 612 613 // --------------------------------------------------------------------------- 614 615 TextOutput& printStrongPointer(TextOutput& to, const void* val) 616 { 617 to << "sp<>(" << val << ")"; 618 return to; 619 } 620 621 TextOutput& printWeakPointer(TextOutput& to, const void* val) 622 { 623 to << "wp<>(" << val << ")"; 624 return to; 625 } 626 627 628 }; // namespace android
1 void RefBase::incStrong(const void* id) const 2 { 3 weakref_impl* const refs = mRefs; 4 refs->incWeak(id); 5 refs->addStrongRef(id); 6 const int32_t c = android_atomic_inc(&refs->mStrong); 7 LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); 8 #if PRINT_REFS 9 LOGD("incStrong of %p from %p: cnt=%d ", this, id, c); 10 #endif 11 if (c != INITIAL_STRONG_VALUE) { 12 return; 13 } 14 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 15 refs->mBase->onFirstRef(); 16 } 17 void RefBase::decStrong(const void* id) const 18 { 19 weakref_impl* const refs = mRefs; 20 refs->removeStrongRef(id); 21 const int32_t c = android_atomic_dec(&refs->mStrong); 22 #if PRINT_REFS 23 LOGD("decStrong of %p from %p: cnt=%d ", this, id, c); 24 #endif 25 LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); 26 if (c == 1) { 27 refs->mBase->onLastStrongRef(id); 28 if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { 29 delete this; 30 } 31 } 32 refs->decWeak(id); 33 }
IBinder

1 #ifndef ANDROID_IBINDER_H 2 #define ANDROID_IBINDER_H 3 #include <utils/Errors.h> 4 #include <utils/RefBase.h> 5 #include <utils/String16.h> 6 #include <utils/Vector.h> 7 8 #define B_PACK_CHARS(c1, c2, c3, c4) 9 ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) 10 namespace android { 11 //forward declaration 12 class BBinder; 13 class BpBinder; 14 class IInterface; 15 class Parcel; 16 17 class IBinder : public virtual RefBase 18 { 19 public: 20 enum { 21 FIRST_CALL_TRANSACTION = 0x00000001, 22 LAST_CALL_TRANSACTION = 0x00ffffff, 23 PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'), 24 DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'), 25 INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'), 26 FLAG_ONEWAY = 0x00000001 27 }; 28 IBinder(); 29 virtual sp<IInterface> queryLocalInterface(const String16& descriptor); 30 virtual const String16& getInterfaceDescriptor() const = 0; 31 virtual bool isBinderAlive() const = 0; 32 virtual status_t pingBinder() = 0; 33 virtual status_t dump(int fd, const Vector<String16>& args) = 0; 34 virtual status_t transact( uint32_t code, 35 const Parcel& data, 36 Parcel* reply, 37 uint32_t flags = 0) = 0; 38 class DeathRecipient : public virtual RefBase 39 { 40 public: 41 virtual void binderDied(const wp<IBinder>& who) = 0; 42 }; 43 virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, 44 void* cookie = NULL, 45 uint32_t flags = 0) = 0; 46 virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, 47 void* cookie = NULL, 48 uint32_t flags = 0, 49 wp<DeathRecipient>* outRecipient = NULL) = 0; 50 51 virtual bool checkSubclass(const void* subclassID) const; 52 typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie); 53 virtual void attachObject( const void* objectID, 54 void* object, 55 void* cleanupCookie, 56 object_cleanup_func func) = 0; 57 virtual void* findObject(const void* objectID) const = 0; 58 virtual void detachObject(const void* objectID) = 0; 59 virtual BBinder* localBinder(); 60 virtual BpBinder* remoteBinder(); 61 protected: 62 virtual ~IBinder(); 63 private: 64 }; 65 }; 66 #endif // ANDROID_IBINDER_H
1 namespace android { 2 //forward declaration 3 class BBinder; 4 class BpBinder; 5 class IInterface; 6 class Parcel; 7 8 class IBinder : public virtual RefBase 9 { 10 public: 11 IBinder(); 12 virtual sp<IInterface> queryLocalInterface(const String16& descriptor); 13 virtual const String16& getInterfaceDescriptor() const = 0; 14 virtual bool isBinderAlive() const = 0; 15 virtual status_t pingBinder() = 0; 16 virtual status_t dump(int fd, const Vector<String16>& args) = 0; 17 virtual status_t transact( uint32_t code, 18 const Parcel& data, 19 Parcel* reply, 20 uint32_t flags = 0) = 0; 21 virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, 22 void* cookie = NULL, 23 uint32_t flags = 0) = 0; 24 virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, 25 void* cookie = NULL, 26 uint32_t flags = 0, 27 wp<DeathRecipient>* outRecipient = NULL) = 0; 28 virtual bool checkSubclass(const void* subclassID) const; 29 typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie); 30 virtual void attachObject(const void* objectID, 31 void* object, 32 void* cleanupCookie, 33 object_cleanup_func func) = 0; 34 virtual void* findObject(const void* objectID) const = 0; 35 virtual void detachObject(const void* objectID) = 0; 36 virtual BBinder* localBinder(); 37 virtual BpBinder* remoteBinder(); 38 protected: 39 virtual ~IBinder(); //stop from creating a Binder object on stack 40 private: 41 }; 42 };
BBinder,BpRefBase
- Binder.h
-
1 /** 2 * Copyright (C) 2008 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_BINDER_H 18 #define ANDROID_BINDER_H 19 20 #include <binder/IBinder.h> 21 22 // --------------------------------------------------------------------------- 23 namespace android { 24 25 class BBinder : public IBinder 26 { 27 public: 28 BBinder(); 29 30 virtual const String16& getInterfaceDescriptor() const; 31 virtual bool isBinderAlive() const; 32 virtual status_t pingBinder(); 33 virtual status_t dump(int fd, const Vector<String16>& args); 34 35 virtual status_t transact( uint32_t code, 36 const Parcel& data, 37 Parcel* reply, 38 uint32_t flags = 0); 39 40 virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, 41 void* cookie = NULL, 42 uint32_t flags = 0); 43 44 virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, 45 void* cookie = NULL, 46 uint32_t flags = 0, 47 wp<DeathRecipient>* outRecipient = NULL); 48 49 virtual void attachObject( const void* objectID, 50 void* object, 51 void* cleanupCookie, 52 object_cleanup_func func); 53 virtual void* findObject(const void* objectID) const; 54 virtual void detachObject(const void* objectID); 55 56 virtual BBinder* localBinder(); 57 58 protected: 59 virtual ~BBinder(); 60 61 virtual status_t onTransact( uint32_t code, 62 const Parcel& data, 63 Parcel* reply, 64 uint32_t flags = 0); 65 66 private: 67 BBinder(const BBinder& o); 68 BBinder& operator=(const BBinder& o); 69 70 class Extras; 71 72 Extras* mExtras; 73 void* mReserved0; 74 }; 75 76 // --------------------------------------------------------------------------- 77 78 class BpRefBase : public virtual RefBase 79 { 80 protected: 81 BpRefBase(const sp<IBinder>& o); 82 virtual ~BpRefBase(); 83 virtual void onFirstRef(); 84 virtual void onLastStrongRef(const void* id); 85 virtual bool onIncStrongAttempted(uint32_t flags, const void* id); 86 87 inline IBinder* remote() { return mRemote; } 88 inline IBinder* remote() const { return mRemote; } 89 90 private: 91 BpRefBase(const BpRefBase& o); 92 BpRefBase& operator=(const BpRefBase& o); 93 94 IBinder* const mRemote; 95 RefBase::weakref_type* mRefs; 96 volatile int32_t mState; 97 }; 98 99 }; // namespace android 100 101 // --------------------------------------------------------------------------- 102 103 #endif // ANDROID_BINDER_H
- Binder.cpp

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 #include <binder/Binder.h> 18 19 #include <utils/Atomic.h> 20 #include <binder/BpBinder.h> 21 #include <binder/IInterface.h> 22 #include <binder/Parcel.h> 23 24 #include <stdio.h> 25 26 namespace android { 27 28 // --------------------------------------------------------------------------- 29 30 IBinder::IBinder() 31 : RefBase() 32 { 33 } 34 35 IBinder::~IBinder() 36 { 37 } 38 39 // --------------------------------------------------------------------------- 40 41 sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor) 42 { 43 return NULL; 44 } 45 46 BBinder* IBinder::localBinder() 47 { 48 return NULL; 49 } 50 51 BpBinder* IBinder::remoteBinder() 52 { 53 return NULL; 54 } 55 56 bool IBinder::checkSubclass(const void* /**subclassID*/) const 57 { 58 return false; 59 } 60 61 // --------------------------------------------------------------------------- 62 63 class BBinder::Extras 64 { 65 public: 66 Mutex mLock; 67 BpBinder::ObjectManager mObjects; 68 }; 69 70 // --------------------------------------------------------------------------- 71 72 BBinder::BBinder() 73 : mExtras(NULL) 74 { 75 } 76 77 bool BBinder::isBinderAlive() const 78 { 79 return true; 80 } 81 82 status_t BBinder::pingBinder() 83 { 84 return NO_ERROR; 85 } 86 87 const String16& BBinder::getInterfaceDescriptor() const 88 { 89 // This is a local static rather than a global static, 90 // to avoid static initializer ordering issues. 91 static String16 sEmptyDescriptor; 92 LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this); 93 return sEmptyDescriptor; 94 } 95 96 status_t BBinder::transact( 97 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 98 { 99 data.setDataPosition(0); 100 101 status_t err = NO_ERROR; 102 switch (code) { 103 case PING_TRANSACTION: 104 reply->writeInt32(pingBinder()); 105 break; 106 default: 107 err = onTransact(code, data, reply, flags); 108 break; 109 } 110 111 if (reply != NULL) { 112 reply->setDataPosition(0); 113 } 114 115 return err; 116 } 117 118 status_t BBinder::linkToDeath( 119 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) 120 { 121 return INVALID_OPERATION; 122 } 123 124 status_t BBinder::unlinkToDeath( 125 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, 126 wp<DeathRecipient>* outRecipient) 127 { 128 return INVALID_OPERATION; 129 } 130 131 status_t BBinder::dump(int fd, const Vector<String16>& args) 132 { 133 return NO_ERROR; 134 } 135 136 void BBinder::attachObject( 137 const void* objectID, void* object, void* cleanupCookie, 138 object_cleanup_func func) 139 { 140 Extras* e = mExtras; 141 142 if (!e) { 143 e = new Extras; 144 if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e), 145 reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) { 146 delete e; 147 e = mExtras; 148 } 149 if (e == 0) return; // out of memory 150 } 151 152 AutoMutex _l(e->mLock); 153 e->mObjects.attach(objectID, object, cleanupCookie, func); 154 } 155 156 void* BBinder::findObject(const void* objectID) const 157 { 158 Extras* e = mExtras; 159 if (!e) return NULL; 160 161 AutoMutex _l(e->mLock); 162 return e->mObjects.find(objectID); 163 } 164 165 void BBinder::detachObject(const void* objectID) 166 { 167 Extras* e = mExtras; 168 if (!e) return; 169 170 AutoMutex _l(e->mLock); 171 e->mObjects.detach(objectID); 172 } 173 174 BBinder* BBinder::localBinder() 175 { 176 return this; 177 } 178 179 BBinder::~BBinder() 180 { 181 if (mExtras) delete mExtras; 182 } 183 184 185 status_t BBinder::onTransact( 186 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 187 { 188 switch (code) { 189 case INTERFACE_TRANSACTION: 190 reply->writeString16(getInterfaceDescriptor()); 191 return NO_ERROR; 192 193 case DUMP_TRANSACTION: { 194 int fd = data.readFileDescriptor(); 195 int argc = data.readInt32(); 196 Vector<String16> args; 197 for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 198 args.add(data.readString16()); 199 } 200 return dump(fd, args); 201 } 202 default: 203 return UNKNOWN_TRANSACTION; 204 } 205 } 206 207 // --------------------------------------------------------------------------- 208 209 enum { 210 // This is used to transfer ownership of the remote binder from 211 // the BpRefBase object holding it (when it is constructed), to the 212 // owner of the BpRefBase object when it first acquires that BpRefBase. 213 kRemoteAcquired = 0x00000001 214 }; 215 216 BpRefBase::BpRefBase(const sp<IBinder>& o) 217 : mRemote(o.get()), mRefs(NULL), mState(0) 218 { 219 extendObjectLifetime(OBJECT_LIFETIME_WEAK); 220 221 if (mRemote) { 222 mRemote->incStrong(this); // Removed on first IncStrong(). 223 mRefs = mRemote->createWeak(this); // Held for our entire lifetime. 224 } 225 } 226 227 BpRefBase::~BpRefBase() 228 { 229 if (mRemote) { 230 if (!(mState&kRemoteAcquired)) { 231 mRemote->decStrong(this); 232 } 233 mRefs->decWeak(this); 234 } 235 } 236 237 void BpRefBase::onFirstRef() 238 { 239 android_atomic_or(kRemoteAcquired, &mState); 240 } 241 242 void BpRefBase::onLastStrongRef(const void* id) 243 { 244 if (mRemote) { 245 mRemote->decStrong(this); 246 } 247 } 248 249 bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id) 250 { 251 return mRemote ? mRefs->attemptIncStrong(this) : false; 252 } 253 254 }; // namespace android
1 status_t BBinder::onTransact( 2 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 3 { 4 switch (code) { 5 case INTERFACE_TRANSACTION: 6 reply->writeString16(getInterfaceDescriptor()); 7 return NO_ERROR; 8 9 case DUMP_TRANSACTION: { 10 int fd = data.readFileDescriptor(); 11 int argc = data.readInt32(); 12 Vector<String16> args; 13 for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 14 args.add(data.readString16()); 15 } 16 return dump(fd, args); 17 } 18 default: 19 return UNKNOWN_TRANSACTION; 20 } 21 }
1 BBinder* BBinder::localBinder() 2 { 3 return this; 4 }
BpBinder
- BpBinder.h
-
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_BPBINDER_H 18 #define ANDROID_BPBINDER_H 19 20 #include <binder/IBinder.h> 21 #include <utils/KeyedVector.h> 22 #include <utils/threads.h> 23 24 // --------------------------------------------------------------------------- 25 namespace android { 26 27 class BpBinder : public IBinder 28 { 29 public: 30 BpBinder(int32_t handle); 31 inline int32_t handle() const { return mHandle; } 32 virtual const String16& getInterfaceDescriptor() const; 33 virtual bool isBinderAlive() const; 34 virtual status_t pingBinder(); 35 virtual status_t dump(int fd, const Vector<String16>& args); 36 virtual status_t transact( uint32_t code, 37 const Parcel& data, 38 Parcel* reply, 39 uint32_t flags = 0); 40 virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, 41 void* cookie = NULL, 42 uint32_t flags = 0); 43 virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, 44 void* cookie = NULL, 45 uint32_t flags = 0, 46 wp<DeathRecipient>* outRecipient = NULL); 47 virtual void attachObject( const void* objectID, 48 void* object, 49 void* cleanupCookie, 50 object_cleanup_func func); 51 virtual void* findObject(const void* objectID) const; 52 virtual void detachObject(const void* objectID); 53 virtual BpBinder* remoteBinder(); 54 status_t setConstantData(const void* data, size_t size); 55 void sendObituary(); 56 class ObjectManager 57 { 58 public: 59 ObjectManager(); 60 ~ObjectManager(); 61 void attach( const void* objectID, 62 void* object, 63 void* cleanupCookie, 64 IBinder::object_cleanup_func func); 65 void* find(const void* objectID) const; 66 void detach(const void* objectID); 67 void kill(); 68 private: 69 ObjectManager(const ObjectManager&); 70 ObjectManager& operator=(const ObjectManager&); 71 struct entry_t 72 { 73 void* object; 74 void* cleanupCookie; 75 IBinder::object_cleanup_func func; 76 }; 77 KeyedVector<const void*, entry_t> mObjects; 78 }; 79 protected: 80 virtual ~BpBinder(); 81 virtual void onFirstRef(); 82 virtual void onLastStrongRef(const void* id); 83 virtual bool onIncStrongAttempted(uint32_t flags, const void* id); 84 private: 85 const int32_t mHandle; 86 struct Obituary { 87 wp<DeathRecipient> recipient; 88 void* cookie; 89 uint32_t flags; 90 }; 91 void reportOneDeath(const Obituary& obit); 92 bool isDescriptorCached() const; 93 mutable Mutex mLock; 94 volatile int32_t mAlive; 95 volatile int32_t mObitsSent; 96 Vector<Obituary>* mObituaries; 97 ObjectManager mObjects; 98 Parcel* mConstantData; 99 mutable String16 mDescriptorCache; 100 }; 101 102 }; // namespace android 103 104 // --------------------------------------------------------------------------- 105 106 #endif // ANDROID_BPBINDER_H
- BpBinder.cpp
-
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 #define LOG_TAG "BpBinder" 18 //#define LOG_NDEBUG 0 19 20 #include <binder/BpBinder.h> 21 22 #include <binder/IPCThreadState.h> 23 #include <utils/Log.h> 24 25 #include <stdio.h> 26 27 //#undef LOGV 28 //#define LOGV(...) fprintf(stderr, __VA_ARGS__) 29 30 namespace android { 31 32 // --------------------------------------------------------------------------- 33 34 BpBinder::ObjectManager::ObjectManager() 35 { 36 } 37 38 BpBinder::ObjectManager::~ObjectManager() 39 { 40 kill(); 41 } 42 43 void BpBinder::ObjectManager::attach( 44 const void* objectID, void* object, void* cleanupCookie, 45 IBinder::object_cleanup_func func) 46 { 47 entry_t e; 48 e.object = object; 49 e.cleanupCookie = cleanupCookie; 50 e.func = func; 51 52 if (mObjects.indexOfKey(objectID) >= 0) { 53 LOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use", 54 objectID, this, object); 55 return; 56 } 57 58 mObjects.add(objectID, e); 59 } 60 61 void* BpBinder::ObjectManager::find(const void* objectID) const 62 { 63 const ssize_t i = mObjects.indexOfKey(objectID); 64 if (i < 0) return NULL; 65 return mObjects.valueAt(i).object; 66 } 67 68 void BpBinder::ObjectManager::detach(const void* objectID) 69 { 70 mObjects.removeItem(objectID); 71 } 72 73 void BpBinder::ObjectManager::kill() 74 { 75 const size_t N = mObjects.size(); 76 LOGV("Killing %d objects in manager %p", N, this); 77 for (size_t i=0; i<N; i++) { 78 const entry_t& e = mObjects.valueAt(i); 79 if (e.func != NULL) { 80 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie); 81 } 82 } 83 84 mObjects.clear(); 85 } 86 87 // --------------------------------------------------------------------------- 88 89 BpBinder::BpBinder(int32_t handle) 90 : mHandle(handle) 91 , mAlive(1) 92 , mObitsSent(0) 93 , mObituaries(NULL) 94 { 95 LOGV("Creating BpBinder %p handle %d ", this, mHandle); 96 97 extendObjectLifetime(OBJECT_LIFETIME_WEAK); 98 IPCThreadState::self()->incWeakHandle(handle); 99 } 100 101 bool BpBinder::isDescriptorCached() const { 102 Mutex::Autolock _l(mLock); 103 return mDescriptorCache.size() ? true : false; 104 } 105 106 const String16& BpBinder::getInterfaceDescriptor() const 107 { 108 if (isDescriptorCached() == false) { 109 Parcel send, reply; 110 // do the IPC without a lock held. 111 status_t err = const_cast<BpBinder*>(this)->transact( 112 INTERFACE_TRANSACTION, send, &reply); 113 if (err == NO_ERROR) { 114 String16 res(reply.readString16()); 115 Mutex::Autolock _l(mLock); 116 // mDescriptorCache could have been assigned while the lock was 117 // released. 118 if (mDescriptorCache.size() == 0) 119 mDescriptorCache = res; 120 } 121 } 122 123 // we're returning a reference to a non-static object here. Usually this 124 // is not something smart to do, however, with binder objects it is 125 // (usually) safe because they are reference-counted. 126 127 return mDescriptorCache; 128 } 129 130 bool BpBinder::isBinderAlive() const 131 { 132 return mAlive != 0; 133 } 134 135 status_t BpBinder::pingBinder() 136 { 137 Parcel send; 138 Parcel reply; 139 status_t err = transact(PING_TRANSACTION, send, &reply); 140 if (err != NO_ERROR) return err; 141 if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA; 142 return (status_t)reply.readInt32(); 143 } 144 145 status_t BpBinder::dump(int fd, const Vector<String16>& args) 146 { 147 Parcel send; 148 Parcel reply; 149 send.writeFileDescriptor(fd); 150 const size_t numArgs = args.size(); 151 send.writeInt32(numArgs); 152 for (size_t i = 0; i < numArgs; i++) { 153 send.writeString16(args[i]); 154 } 155 status_t err = transact(DUMP_TRANSACTION, send, &reply); 156 return err; 157 } 158 159 status_t BpBinder::transact( 160 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 161 { 162 // Once a binder has died, it will never come back to life. 163 if (mAlive) { 164 status_t status = IPCThreadState::self()->transact( 165 mHandle, code, data, reply, flags); 166 if (status == DEAD_OBJECT) mAlive = 0; 167 return status; 168 } 169 170 return DEAD_OBJECT; 171 } 172 173 status_t BpBinder::linkToDeath( 174 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) 175 { 176 Obituary ob; 177 ob.recipient = recipient; 178 ob.cookie = cookie; 179 ob.flags = flags; 180 181 LOG_ALWAYS_FATAL_IF(recipient == NULL, 182 "linkToDeath(): recipient must be non-NULL"); 183 184 { 185 AutoMutex _l(mLock); 186 187 if (!mObitsSent) { 188 if (!mObituaries) { 189 mObituaries = new Vector<Obituary>; 190 if (!mObituaries) { 191 return NO_MEMORY; 192 } 193 LOGV("Requesting death notification: %p handle %d ", this, mHandle); 194 getWeakRefs()->incWeak(this); 195 IPCThreadState* self = IPCThreadState::self(); 196 self->requestDeathNotification(mHandle, this); 197 self->flushCommands(); 198 } 199 ssize_t res = mObituaries->add(ob); 200 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res; 201 } 202 } 203 204 return DEAD_OBJECT; 205 } 206 207 status_t BpBinder::unlinkToDeath( 208 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, 209 wp<DeathRecipient>* outRecipient) 210 { 211 AutoMutex _l(mLock); 212 213 if (mObitsSent) { 214 return DEAD_OBJECT; 215 } 216 217 const size_t N = mObituaries ? mObituaries->size() : 0; 218 for (size_t i=0; i<N; i++) { 219 const Obituary& obit = mObituaries->itemAt(i); 220 if ((obit.recipient == recipient 221 || (recipient == NULL && obit.cookie == cookie)) 222 && obit.flags == flags) { 223 const uint32_t allFlags = obit.flags|flags; 224 if (outRecipient != NULL) { 225 *outRecipient = mObituaries->itemAt(i).recipient; 226 } 227 mObituaries->removeAt(i); 228 if (mObituaries->size() == 0) { 229 LOGV("Clearing death notification: %p handle %d ", this, mHandle); 230 IPCThreadState* self = IPCThreadState::self(); 231 self->clearDeathNotification(mHandle, this); 232 self->flushCommands(); 233 delete mObituaries; 234 mObituaries = NULL; 235 } 236 return NO_ERROR; 237 } 238 } 239 240 return NAME_NOT_FOUND; 241 } 242 243 void BpBinder::sendObituary() 244 { 245 LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s ", 246 this, mHandle, mObitsSent ? "true" : "false"); 247 248 mAlive = 0; 249 if (mObitsSent) return; 250 251 mLock.lock(); 252 Vector<Obituary>* obits = mObituaries; 253 if(obits != NULL) { 254 LOGV("Clearing sent death notification: %p handle %d ", this, mHandle); 255 IPCThreadState* self = IPCThreadState::self(); 256 self->clearDeathNotification(mHandle, this); 257 self->flushCommands(); 258 mObituaries = NULL; 259 } 260 mObitsSent = 1; 261 mLock.unlock(); 262 263 LOGV("Reporting death of proxy %p for %d recipients ", 264 this, obits ? obits->size() : 0); 265 266 if (obits != NULL) { 267 const size_t N = obits->size(); 268 for (size_t i=0; i<N; i++) { 269 reportOneDeath(obits->itemAt(i)); 270 } 271 272 delete obits; 273 } 274 } 275 276 void BpBinder::reportOneDeath(const Obituary& obit) 277 { 278 sp<DeathRecipient> recipient = obit.recipient.promote(); 279 LOGV("Reporting death to recipient: %p ", recipient.get()); 280 if (recipient == NULL) return; 281 282 recipient->binderDied(this); 283 } 284 285 286 void BpBinder::attachObject( 287 const void* objectID, void* object, void* cleanupCookie, 288 object_cleanup_func func) 289 { 290 AutoMutex _l(mLock); 291 LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects); 292 mObjects.attach(objectID, object, cleanupCookie, func); 293 } 294 295 void* BpBinder::findObject(const void* objectID) const 296 { 297 AutoMutex _l(mLock); 298 return mObjects.find(objectID); 299 } 300 301 void BpBinder::detachObject(const void* objectID) 302 { 303 AutoMutex _l(mLock); 304 mObjects.detach(objectID); 305 } 306 307 BpBinder* BpBinder::remoteBinder() 308 { 309 return this; 310 } 311 312 BpBinder::~BpBinder() 313 { 314 LOGV("Destroying BpBinder %p handle %d ", this, mHandle); 315 316 IPCThreadState* ipc = IPCThreadState::self(); 317 318 mLock.lock(); 319 Vector<Obituary>* obits = mObituaries; 320 if(obits != NULL) { 321 if (ipc) ipc->clearDeathNotification(mHandle, this); 322 mObituaries = NULL; 323 } 324 mLock.unlock(); 325 326 if (obits != NULL) { 327 // XXX Should we tell any remaining DeathRecipient 328 // objects that the last strong ref has gone away, so they 329 // are no longer linked? 330 delete obits; 331 } 332 333 if (ipc) { 334 ipc->expungeHandle(mHandle, this); 335 ipc->decWeakHandle(mHandle); 336 } 337 } 338 339 void BpBinder::onFirstRef() 340 { 341 LOGV("onFirstRef BpBinder %p handle %d ", this, mHandle); 342 IPCThreadState* ipc = IPCThreadState::self(); 343 if (ipc) ipc->incStrongHandle(mHandle); 344 } 345 346 void BpBinder::onLastStrongRef(const void* id) 347 { 348 LOGV("onLastStrongRef BpBinder %p handle %d ", this, mHandle); 349 IF_LOGV() { 350 printRefs(); 351 } 352 IPCThreadState* ipc = IPCThreadState::self(); 353 if (ipc) ipc->decStrongHandle(mHandle); 354 } 355 356 bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id) 357 { 358 LOGV("onIncStrongAttempted BpBinder %p handle %d ", this, mHandle); 359 IPCThreadState* ipc = IPCThreadState::self(); 360 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false; 361 } 362 363 // --------------------------------------------------------------------------- 364 365 }; // namespace android
1 status_t BpBinder::transact( 2 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 3 { 4 // Once a binder has died, it will never come back to life. 5 if (mAlive) { 6 status_t status = IPCThreadState::self()->transact( 7 mHandle, code, data, reply, flags); 8 if (status == DEAD_OBJECT) mAlive = 0; 9 return status; 10 } 11 12 return DEAD_OBJECT; 13 }
IInterface
- IInterface.cpp
-
1 #include <binder/IInterface.h> 2 namespace android { 3 IInterface::IInterface() 4 : RefBase() { 5 } 6 IInterface::~IInterface() { 7 } 8 sp<IBinder> IInterface::asBinder() 9 { 10 return this ? onAsBinder() : NULL; 11 } 12 sp<const IBinder> IInterface::asBinder() const 13 { 14 return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL; 15 } 16 };
- IInterface.h
-
1 class IInterface : public virtual RefBase 2 { 3 public: 4 IInterface(); 5 sp<IBinder> asBinder(); 6 sp<const IBinder> asBinder() const; 7 8 protected: 9 virtual ~IInterface(); 10 virtual IBinder* onAsBinder() = 0; 11 };
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 // 18 #ifndef ANDROID_IINTERFACE_H 19 #define ANDROID_IINTERFACE_H 20 21 #include <binder/Binder.h> 22 23 namespace android { 24 25 // ---------------------------------------------------------------------- 26 27 class IInterface : public virtual RefBase 28 { 29 public: 30 IInterface(); 31 sp<IBinder> asBinder(); 32 sp<const IBinder> asBinder() const; 33 34 protected: 35 virtual ~IInterface(); 36 virtual IBinder* onAsBinder() = 0; 37 }; 38 39 // ---------------------------------------------------------------------- 40 41 template<typename INTERFACE> 42 inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) 43 { 44 return INTERFACE::asInterface(obj); 45 } 46 47 // ---------------------------------------------------------------------- 48 49 template<typename INTERFACE> 50 class BnInterface : public INTERFACE, public BBinder 51 { 52 public: 53 virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); 54 virtual const String16& getInterfaceDescriptor() const; 55 56 protected: 57 virtual IBinder* onAsBinder(); 58 }; 59 60 // ---------------------------------------------------------------------- 61 62 template<typename INTERFACE> 63 class BpInterface : public INTERFACE, public BpRefBase 64 { 65 public: 66 BpInterface(const sp<IBinder>& remote); 67 68 protected: 69 virtual IBinder* onAsBinder(); 70 }; 71 72 // ---------------------------------------------------------------------- 73 74 #define DECLARE_META_INTERFACE(INTERFACE) 75 static const android::String16 descriptor; 76 static android::sp<I##INTERFACE> asInterface( 77 const android::sp<android::IBinder>& obj); 78 virtual const android::String16& getInterfaceDescriptor() const; 79 I##INTERFACE(); 80 virtual ~I##INTERFACE(); 81 82 83 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 84 const android::String16 I##INTERFACE::descriptor(NAME); 85 const android::String16& 86 I##INTERFACE::getInterfaceDescriptor() const { 87 return I##INTERFACE::descriptor; 88 } 89 android::sp<I##INTERFACE> I##INTERFACE::asInterface( 90 const android::sp<android::IBinder>& obj) 91 { 92 android::sp<I##INTERFACE> intr; 93 if (obj != NULL) { 94 intr = static_cast<I##INTERFACE*>( 95 obj->queryLocalInterface( 96 I##INTERFACE::descriptor).get()); 97 if (intr == NULL) { 98 intr = new Bp##INTERFACE(obj); 99 } 100 } 101 return intr; 102 } 103 I##INTERFACE::I##INTERFACE() { } 104 I##INTERFACE::~I##INTERFACE() { } 105 106 107 #define CHECK_INTERFACE(interface, data, reply) 108 if (!data.checkInterface(this)) { return PERMISSION_DENIED; } 109 110 111 // ---------------------------------------------------------------------- 112 // No user-serviceable parts after this... 113 114 template<typename INTERFACE> 115 inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface( 116 const String16& _descriptor) 117 { 118 if (_descriptor == INTERFACE::descriptor) return this; 119 return NULL; 120 } 121 122 template<typename INTERFACE> 123 inline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const 124 { 125 return INTERFACE::getInterfaceDescriptor(); 126 } 127 128 template<typename INTERFACE> 129 IBinder* BnInterface<INTERFACE>::onAsBinder() 130 { 131 return this; 132 } 133 134 template<typename INTERFACE> 135 inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) 136 : BpRefBase(remote) 137 { 138 } 139 140 template<typename INTERFACE> 141 inline IBinder* BpInterface<INTERFACE>::onAsBinder() 142 { 143 return remote(); 144 } 145 146 // ---------------------------------------------------------------------- 147 148 }; // namespace android 149 150 #endif // ANDROID_IINTERFACE_H
1 template<typename INTERFACE> 2 IBinder* BnInterface<INTERFACE>::onAsBinder() 3 { 4 return this; 5 }
template<typename INTERFACE> inline IBinder* BpInterface<INTERFACE>::onAsBinder() { return remote(); }
- Every process shall open "dev/binder" as shared memory used for communication between processes.
-
1 ProcessState::ProcessState() 2 : mDriverFD(open_driver()) 3 , mVMStart(MAP_FAILED) 4 , mManagesContexts(false) 5 , mBinderContextCheckFunc(NULL) 6 , mBinderContextUserData(NULL) 7 , mThreadPoolStarted(false) 8 , mThreadPoolSeq(1) 9 { 10 if (mDriverFD >= 0) { 11 #if !defined(HAVE_WIN32_IPC) 12 mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); 13 if (mVMStart == MAP_FAILED) { 14 LOGE("Using /dev/binder failed: unable to mmap transaction memory. "); 15 close(mDriverFD); 16 mDriverFD = -1; 17 } 18 #else 19 mDriverFD = -1; 20 #endif 21 } 22 LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); 23 }
- Every service or client has a binder reference to service manager with default 0# reference, which is BpServiceManager
-
1 sp<IServiceManager> defaultServiceManager() 2 { 3 if (gDefaultServiceManager != NULL) return gDefaultServiceManager; 4 5 { 6 AutoMutex _l(gDefaultServiceManagerLock); 7 if (gDefaultServiceManager == NULL) { 8 gDefaultServiceManager = interface_cast<IServiceManager>( 9 ProcessState::self()->getContextObject(NULL)); 10 } 11 } 12 return gDefaultServiceManager; 13 } 14 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) 15 { 16 return getStrongProxyForHandle(0); 17 } 18 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) 19 { 20 sp<IBinder> result; 21 22 AutoMutex _l(mLock); 23 handle_entry* e = lookupHandleLocked(handle); 24 if (e != NULL) { 25 IBinder* b = e->binder; 26 if (b == NULL || !e->refs->attemptIncWeak(this)) { 27 b = new BpBinder(handle); 28 e->binder = b; 29 if (b) e->refs = b->getWeakRefs(); 30 result = b; 31 } else { 32 result.force_set(b); 33 e->refs->decWeak(this); 34 } 35 } 36 return result; 37 } 38 BpBinder::BpBinder(int32_t handle) 39 : mHandle(handle) 40 , mAlive(1) 41 , mObitsSent(0) 42 , mObituaries(NULL) 43 { 44 extendObjectLifetime(OBJECT_LIFETIME_WEAK); 45 IPCThreadState::self()->incWeakHandle(handle); 46 } 47 template<typename INTERFACE> 48 inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) 49 { 50 return INTERFACE::asInterface(obj); 51 } 52 #define DECLARE_META_INTERFACE(ServiceManager) 53 static const android::String16 descriptor; 54 static android::sp<IServiceManager> asServiceManager( 55 const android::sp<android::IBinder>& obj); 56 virtual const android::String16& getServiceManagerDescriptor() const; 57 IServiceManager(); 58 virtual ~IServiceManager(); 59 #define IMPLEMENT_META_INTERFACE(ServiceManager, NAME) 60 const android::String16 IServiceManager::descriptor(NAME); 61 const android::String16& 62 IServiceManager::getServiceManagerDescriptor() const { 63 return IServiceManager::descriptor; 64 } 65 android::sp<IServiceManager> IServiceManager::asInterface( 66 const android::sp<android::IBinder>& obj) 67 { 68 android::sp<IServiceManager> intr; 69 if (obj != NULL) { 70 intr = static_cast<IServiceManager*>( 71 obj->queryLocalServiceManager( 72 IServiceManager::descriptor).get()); 73 if (intr == NULL) { 74 intr = new BpServiceManager(obj); //obj is remote 75 } 76 } 77 return intr; 78 } 79 IServiceManager::IServiceManager() { } 80 IServiceManager::~IServiceManager() { }
- Now we have a BpServiceManager
-
class BpServiceManager : public BpInterface<IServiceManager> { public: BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { } virtual sp<IBinder> getService(const String16& name) const { unsigned n; for (n = 0; n < 5; n++){ sp<IBinder> svc = checkService(name); if (svc != NULL) return svc; LOGI("Waiting for service %s... ", String8(name).string()); sleep(1); } return NULL; } virtual sp<IBinder> checkService( const String16& name) const { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); return reply.readStrongBinder(); } virtual status_t addService(const String16& name, const sp<IBinder>& service) { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); data.writeStrongBinder(service); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; } virtual Vector<String16> listServices() { Vector<String16> res; int n = 0; for (;;) { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeInt32(n++); status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply); if (err != NO_ERROR) break; res.add(reply.readString16()); } return res; } };
- Every service add itself into service manager
-
1 void MediaPlayerService::instantiate() { 2 defaultServiceManager()->addService( 3 String16("media.player"), new MediaPlayerService());//create a new service object to give ServiceMananger 4 }
- Now we call addService() of BpServiceManager
-
1 virtual status_t addService(const String16& name, const sp<IBinder>& service) 2 { 3 Parcel data, reply; 4 data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); 5 data.writeString16(name); 6 data.writeStrongBinder(service); 7 status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); 8 return err == NO_ERROR ? reply.readExceptionCode() : err; 9 }
- Where is remote()?
-
1 class BpServiceManager : public BpInterface<IServiceManager> 2 3 template<typename INTERFACE> 4 IBinder* BnInterface<INTERFACE>::onAsBinder() 5 { 6 return this; 7 } 8 template<typename INTERFACE> 9 inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) 10 : BpRefBase(remote) 11 { 12 } 13 template<typename INTERFACE> 14 inline IBinder* BpInterface<INTERFACE>::onAsBinder() 15 { 16 return remote(); 17 }
- where is remote from??
- Ohh.....for BpServiceManager,it is this
-
1 intr = new BpServiceManager(obj); 2 class BpServiceManager : public BpInterface<IServiceManager> 3 { 4 public: 5 BpServiceManager(const sp<IBinder>& impl) 6 : BpInterface<IServiceManager>(impl) 7 { 8 } 9 ......... 10 }
- Write data to binder
-
1 status_t BpBinder::transact( 2 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 3 { 4 // Once a binder has died, it will never come back to life. 5 if (mAlive) { 6 status_t status = 7 IPCThreadState::self()->transact(mHandle, code, data, reply, flags); 8 if (status == DEAD_OBJECT) mAlive = 0; 9 return status; 10 } 11 return DEAD_OBJECT; 12 } 13 status_t IPCThreadState::transact(int32_t handle, 14 uint32_t code, const Parcel& data, 15 Parcel* reply, uint32_t flags) 16 { 17 status_t err = data.errorCheck(); 18 flags |= TF_ACCEPT_FDS; 19 IF_LOG_TRANSACTIONS() { 20 TextOutput::Bundle _b(alog); 21 alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand " 22 << handle << " / code " << TypeCode(code) << ": " 23 << indent << data << dedent << endl; 24 } 25 if (err == NO_ERROR) { 26 LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(), 27 (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY"); 28 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); 29 } 30 ................ 31 } 32 status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, 33 int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) 34 { 35 binder_transaction_data tr; 36 tr.target.handle = handle; 37 tr.code = code; 38 tr.flags = binderFlags; 39 tr.cookie = 0; 40 tr.sender_pid = 0; 41 tr.sender_euid = 0; 42 43 const status_t err = data.errorCheck(); 44 if (err == NO_ERROR) { 45 tr.data_size = data.ipcDataSize(); 46 tr.data.ptr.buffer = data.ipcData(); 47 tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t); 48 tr.data.ptr.offsets = data.ipcObjects(); 49 } else if (statusBuffer) { 50 tr.flags |= TF_STATUS_CODE; 51 *statusBuffer = err; 52 tr.data_size = sizeof(status_t); 53 tr.data.ptr.buffer = statusBuffer; 54 tr.offsets_size = 0; 55 tr.data.ptr.offsets = NULL; 56 } else { 57 return (mLastError = err); 58 } 59 mOut.writeInt32(cmd); 60 mOut.write(&tr, sizeof(tr)); 61 return NO_ERROR; 62 }
- BnServiceManager handle
-
status_t BnServiceManager::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { //printf("ServiceManager received: "); data.print(); switch(code) { case GET_SERVICE_TRANSACTION: { CHECK_INTERFACE(IServiceManager, data, reply); String16 which = data.readString16(); sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which); reply->writeStrongBinder(b); return NO_ERROR; } break; case CHECK_SERVICE_TRANSACTION: { CHECK_INTERFACE(IServiceManager, data, reply); String16 which = data.readString16(); sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which); reply->writeStrongBinder(b); return NO_ERROR; } break; case ADD_SERVICE_TRANSACTION: { CHECK_INTERFACE(IServiceManager, data, reply); String16 which = data.readString16(); sp<IBinder> b = data.readStrongBinder(); status_t err = addService(which, b); reply->writeInt32(err); return NO_ERROR; } break; case LIST_SERVICES_TRANSACTION: { CHECK_INTERFACE(IServiceManager, data, reply); Vector<String16> list = listServices(); const size_t N = list.size(); reply->writeInt32(N); for (size_t i=0; i<N; i++) { reply->writeString16(list[i]); } return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } }
http://www.cnblogs.com/Hwangroid/archive/2011/07/13/2105310.html
http://www.cnblogs.com/bluestorm/archive/2011/11/05/2298125.html
http://www.cnblogs.com/freeliver54/archive/2012/06/13/2547739.html
http://www.cnblogs.com/-OYK/archive/2011/07/31/2122981.html
http://www.cnblogs.com/yunsean/archive/2011/04/15/2017213.html
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html
http://www.cnblogs.com/ThinkingWorld/articles/1861739.html
http://www.cnblogs.com/linucos/archive/2012/05/24/2516623.html