zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    SPOJ-BRCKTS (括号序列,线段树)
    bzoj 2223 [Coci 2009]PATULJCI
    bzoj 1049 [HAOI2006]数字序列
    bzoj2091 [Poi2010]The Minima Game
    bzoj 1016 [JSOI2008]最小生成树计数
    bzoj5105 晨跑 数论lcm
    bzoj 1211 [HNOI2004]树的计数
    bzoj 1430 小猴打架 prufer 性质
    Swing界面组件的通用属性
    数字调节控件JSpinner的使用
  • 原文地址:https://www.cnblogs.com/iiiDragon/p/3276916.html
Copyright © 2011-2022 走看看