Android IPC

 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
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.h
  • 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
    RefBase.cpp
     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
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.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
Binder.cpp
 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.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
    BpBinder.cpp
     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
    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 }
    ProcessState.self()
  • 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;
        }
    };
    BpServiceManager
  • 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 }
    View Code
  • 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

原文地址:https://www.cnblogs.com/iiiDragon/p/3276916.html