本文参考《Android系统源代码情景分析》,作者罗升阳。

一、测试代码:

~/Android/external/binder/server

----FregServer.cpp

~/Android/external/binder/common

----IFregService.cpp

----IFregService.h

~/Android/external/binder/client

----FregClient.cpp


Binder库(libbinder)代码:

~/Android/frameworks/base/libs/binder

----BpBinder.cpp

----Parcel.cpp

----ProcessState.cpp

----Binder.cpp

----IInterface.cpp

----IPCThreadState.cpp

----IServiceManager.cpp

----Static.cpp

~/Android/frameworks/base/include/binder

----Binder.h

----BpBinder.h

----IInterface.h

----IPCThreadState.h

----IServiceManager.h

----IBinder.h

----Parcel.h

----ProcessState.h


驱动层代码:

~/Android//kernel/goldfish/drivers/staging/android

----binder.c

----binder.h


二、源码分析

1、程序首先开始从Service进程FregServer.cpp的main函数开始执行

~/Android/external/binder/server

----FregServer.cpp

class FregService : public BnFregService{        ...........public:static void instantiate(){defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService());}        ...........};int main(int argc, char** argv){FregService::instantiate();ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();return 0;}
main函数首先调用静态方法instantiate,在instantiate中调用了defaultServiceManager(),因为include#include <binder/IServiceManager.h>,所以可以调用 defaultServiceManager()函数实现如下:

~/Android/frameworks/base/libs/binder

----IServiceManager.cpp

sp<IServiceManager> defaultServiceManager(){    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//如果已经创建了代理对象,那么就直接返回        {        AutoMutex _l(gDefaultServiceManagerLock);//使用锁,来实现单例模式        if (gDefaultServiceManager == NULL) {            gDefaultServiceManager = interface_cast<IServiceManager>(//分三步获取Service Manager代理对象                ProcessState::self()->getContextObject(NULL));        }    }        return gDefaultServiceManager;}
其中gDefaultServiceManagerLock,gDefaultServiceManager都定义在Static.cpp中。

~/Android/frameworks/base/libs/binder

----Static.cpp

Mutex gDefaultServiceManagerLock;   //锁sp<IServiceManager> gDefaultServiceManager; //IServiceManager的强指针
全局变量 gDefaultServiceManager是一个类型为IServiceManager的强指针,它指向进程内的一个BpServiceManager对象,即Service Manager代理对象;而全局变量gDefaultServiceManagerLock是用来保证一个进程至多只有一个Service Manager代理对象。结合锁机制来保证对象在进程中的唯一性,这是单例设计模式的经典实现。

如果已经创建了代理对象,那么就直接返回。如果没有创建,那么分三步创建:

(1)、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象。

(2)、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象

(3)、调用模板函数interface_cast<IServiceManager>将前面获得的Binder代理对象封装成一个Service Manager代理对象。


2、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

sp<ProcessState> ProcessState::self(){    if (gProcess != NULL) return gProcess;//如果已经创建了,就直接返回        AutoMutex _l(gProcessMutex);    if (gProcess == NULL) gProcess = new ProcessState;//创建ProcessState对象    return gProcess;}
其中gProcess,gProcessMutex都位于Static.cpp中

Mutex gProcessMutex;sp<ProcessState> gProcess;
全局变量gProcess是一个类型为ProcessState的强指针,它指向进程内的一个ProcessState对象;而全局变量gProcessMutex是一个互斥锁,是用来保证一个进程至多只有一个ProcessState对象的,同样是一个单例模式。


首次进入,故创建ProcessState对象。

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

ProcessState::ProcessState()    : mDriverFD(open_driver())    , mVMStart(MAP_FAILED)    .....{    if (mDriverFD >= 0) {       ...........        // mmap the binder, providing a chunk of virtual address space to receive transactions.        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);       ...........}
在初始化构造函数中调用了open_driver方法。

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

static int open_driver(){    if (gSingleProcess) {        return -1;    }    int fd = open("/dev/binder", O_RDWR);//又一个进程打开了设备文件,binder_procs又多了一个进程的结构体    if (fd >= 0) {        fcntl(fd, F_SETFD, FD_CLOEXEC);        int vers;#if defined(HAVE_ANDROID_OS)        status_t result = ioctl(fd, BINDER_VERSION, &vers);//调用ioctl传入BINDER_VERSION参数来获取vers#else        status_t result = -1;        errno = EPERM;#endif        if (result == -1) {            LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));            close(fd);            fd = -1;        }        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {            LOGE("Binder driver protocol does not match user space protocol!");            close(fd);            fd = -1;        }#if defined(HAVE_ANDROID_OS)        size_t maxThreads = 15;        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);//调用ioctl传入BINDER_SET_MAX_THREADS参数来设备该进程所支持的最大线程数        if (result == -1) {            LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));        }#endif            } else {        LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));    }    return fd;}
open_driver首先调用了open打开设备文件,在http://blog.csdn.net/jltxgcy/article/details/25797011这盘文章中已经讲解了驱动层的binder_open所做的事。然后的调用ioctl传入BINDER_VERSION参数来获取vers。最后调用ioctl传入BINDER_SET_MAX_THREADS参数来设备该进程所支持的最大线程数。

在初始化列表中调用mmap把设备文件/dev/binder映射到进程的地址空间,其实将/dev/binder映射到进程的地址空间实际上是请求Binder驱动程序为进程分配内核缓冲区。


3、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){    if (supportsProcesses()) {//为true        return getStrongProxyForHandle(0);    } else {        return getContextObject(String16("default"), caller);    }}

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

bool ProcessState::supportsProcesses() const{    return mDriverFD >= 0;}
由于在open_driver时,mDriverFD已经大于0,所以程序开始执行getStrongProxyForHandle(0)。

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){    sp<IBinder> result;    AutoMutex _l(mLock);    handle_entry* e = lookupHandleLocked(handle);//检查成员变量mHandleToObject是否已经存在一个与句柄值handle对应的handle_entry结构体    if (e != NULL) {        // We need to create a new BpBinder if there isn't currently one, OR we        // are unable to acquire a weak reference on this current one.  See comment        // in getWeakProxyForHandle() for more info about this.        IBinder* b = e->binder;        if (b == NULL || !e->refs->attemptIncWeak(this)) {//如果进程尚未为句柄值handle创建过Binder代理对象,或者创建了Binder代理对象但已经销毁了            b = new BpBinder(handle); //Binder代理对象,handle为0            e->binder = b;//保存再e的成员变量binder中            if (b) e->refs = b->getWeakRefs();//将弱引用计数对象保存在e的成员变量refs中            result = b;//返回结果        } else {//如果进程已经创建了Binder代理对象,并且没有销毁,那么直接返回            // This little bit of nastyness is to allow us to add a primary            // reference to the remote proxy when this team doesn't have one            // but another team is sending the handle to us.            result.force_set(b);//设置返回结果result            e->refs->decWeak(this);//减少弱引用计数,因为attemptIncWeak增加了弱引用计数        }    }    return result;}
参数handle的值等于0,表示要创建的Binder代理对象的句柄值等于0,即要创建一个Binder代理对象。Binder库为每个进程维护了一个handle_entry类型的Binder代理对象列表,它以句柄值作为关键字来维护进程内部所有的Binder代理对象。这个Binder代理对象列表保存在ProcessState类的成员变量mHandleToObject,它的定义如下:

~/Android/frameworks/base/include/binder

----ProcessState.h

class ProcessState : public virtual RefBase{            .......                       struct handle_entry {                IBinder* binder;//Binder代理对象                RefBase::weakref_type* refs;//一个弱引用计数对象            };                        ..........            Vector<handle_entry>mHandleToObject;//列表            .........};

每一个Binder代理对象都使用一个handle_entry结构体来描述。结构体handle_entry的两个成员变量binder和refs分别指向一个Binder代理对象,以及它内部的一个弱引用计数对象。

回到ProcessState类的成员函数getStrongProxyForHandle(0),首先调用成员函数lookupHandleLocked来检查成员变量mHandleToObject是否已经存在一个与句柄值handle对应的handle_entry结构体,它的实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle){    const size_t N=mHandleToObject.size();//列表的大小    if (N <= (size_t)handle) {如果句柄值大于或者等于列表大小,否则直接返回指向该结构体的指针        handle_entry e;//创建handle_entry结构体        e.binder = NULL;//初始化        e.refs = NULL;        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);//插入到对应位置        if (err < NO_ERROR) return NULL;    }    return &mHandleToObject.editItemAt(handle);//返回指向该结构体的指针}
一个Binder代理对象的句柄值同时也是它在列表mHandleToObject中的索引值。首先检查句柄值handle是否大于或者等于列表mHandleToObject的大小,如果是,那么mHandleToObject列表里面就不存在一个与句柄值handle对应的handle_entry结构体,那么创建一个handle_entry结构体,并插入到对应位置,最后返回指向该结构体的指针。

程序继续执行,如果hanle_entry结构体e的成员变量binder的值为NULL,说明进程尚未为句柄值handle创建过Binder代理对象,因此就会根据句柄值handle创建一个Binder代理对象,并且将它保存在handle_entry结构体e的成员变量binder中。并且把弱引用计数对象保存在e的成员变量refs中。

如果hanle_entry结构体e的成员变量binder的值不为NULL,即它已经指向了一个Binder代理对象,就需要继续检查这个Binder代理对象是否还活着,方法是调用它的弱引用计数对象的成员函数attemptIncWeek来尝试增加它的弱引用数。由于Binder代理对象(即BpBinder对象)的生命周期是受弱引用计数控制的,因此如果不能成功增加它的弱引用计数,那么就说明它已经被销毁了。在这种情况下,也需要重新为句柄值handle创建一个Binder代理对象。

如果handle_entry结构体e成员变量binder的值不等于NULL,并且调用它的成员attmptIncWeek能够成功地增加与它对应的一个Binder代理对象的弱引用计数,那么就说明在进程中已经有一个Binder代理对象与句柄值handle相对应,并且这个Binder代理对象是有效的,因此,可以直接将它返回调用调用者。注意函数在将这个Binder代理对象返回给调用者之前,会减少它的弱引用计数,因为attemptIncWeek增加了弱应用计数。


下面我们分析下如何创建Binder代理对象,即new BpBinder(handle)究竟做了什么?

~/Android/frameworks/base/include/binder
----BpBinder.cpp

BpBinder::BpBinder(int32_t handle)    : mHandle(handle)//mHandle等于0    , mAlive(1)    , mObitsSent(0)    , mObituaries(NULL){    LOGV("Creating BpBinder %p handle %d\n", this, mHandle);    extendObjectLifetime(OBJECT_LIFETIME_WEAK);    IPCThreadState::self()->incWeakHandle(handle);//调用了IPCThreadState的成员函数self()}
又调用了IPCThreadState的成员函数self(),实现如下:

~/Android/frameworks/base/libs/binder

----IPCThreadState.cpp

IPCThreadState* IPCThreadState::self(){    if (gHaveTLS) {//第二次为truerestart:        const pthread_key_t k = gTLS;//利用第一次创建的gTLS        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);//获取IPCThreadState类,有pthread_getspecific(k),就一定有phread_setspecific;从线程本地存储空间获取对象        if (st) return st;        return new IPCThreadState;//构造函数中有phread_setspecific    }        if (gShutdown) return NULL;        pthread_mutex_lock(&gTLSMutex);    if (!gHaveTLS) {//第一次执行这里,创建了gTLS        if (pthread_key_create(&gTLS, threadDestructor) != 0) {//创建线程本地存储空间            pthread_mutex_unlock(&gTLSMutex);            return NULL;        }        gHaveTLS = true;//为第二次做准备    }    pthread_mutex_unlock(&gTLSMutex);    goto restart;//返回开头}
第一次,gHaveTLS为false,所以进入下面的代码,创建了gTLS,而且gHaveTLS为true。第二次gHaveTLS为true,利用第一次创建的gTLS,获取IPCThreadState类,如果获取不到,就创建该类,在创建该类的过程中,调用了phread_setspecific函数,new IPCThreadState实现如下:

~/Android/frameworks/base/libs/binder

----IPCThreadState.cpp

IPCThreadState::IPCThreadState()    : mProcess(ProcessState::self()),//因为单例模式,就是刚才创建的ProcessState对象      mMyThreadId(androidGetTid()),      mStrictModePolicy(0),      mLastTransactionBinderFlags(0){    pthread_setspecific(gTLS, this);//调用了这个函数,下次就是pthread_getspecific获取到了;将对象保存在线程本地存储空间    clearCaller();    mIn.setDataCapacity(256);//输入容量256    mOut.setDataCapacity(256);//输出容量256}

由于是单例模式,所以mProcess保存的就是刚刚创建的ProcessState对象。下次调用IPCThreadState::self只要在同一个线程中,就返回刚刚创建的IPCThreadState对象,因为每个线程有独一无二的gTLS。


开始执行incWeakHandle,参考博客http://blog.csdn.net/jltxgcy/article/details/27638717,此时Server进程等到下次使用IO控制命令BINDER_WRITE_READ进入到Binder驱动程序时,再请求Binder驱动程序增加相应的Binder引用对象的强引用计数和弱引用计数。



4、调用模板函数interface_cast<IServiceManager>将前面获得的Binder代理对象封装成一个Service Manager代理对象,因为#include <binder/IServiceManager.h>。IServiceManager.h包含了#include <binder/IInterface.h>,所以可以调用。

~/Android/frameworks/base/include/binder

----IInterface.h

template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){    return INTERFACE::asInterface(obj);}
由于INTERFACE为IServiceManger,所以展开如下:

template<typename IServiceManager>inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){    return IServiceManager::asInterface(obj);//静态方法所以直接调用}
调用IServiceManager接口的成员函数asInterface,将一个句柄值为0的Binder代理对象封装为一个Service Manger代理对象。

IServiceManager接口的成员函数asInterface是通过宏IMPLEMENT_META_INTERFACE实现,如下所示:

~/Android/frameworks/base/libs/binder

----IServiceManager.cpp

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
展开后如下:

android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)                                              {                                                                                     android::sp<IServiceManager> intr;                                                    if (obj != NULL) {                                                                     intr = static_cast<IServiceManager*>(                                                                      obj->queryLocalInterface(IServiceManager::descriptor).get());//返回NULLif (intr == NULL) {                intr = new BpServiceManager(obj);  //创建了Service Manager代理对象                                      }                                          }return intr;                                  }   
参数obj指向一个Binder代理对象,即一个BpBinder对象,它的成员函数queryLocalInterface的返回值为NULL。因此,最后会创建一个Service Manager代理对象,即一个BpServiceManger对象,并且将它的IServiceManager接口返回给调用者。

uml类图如下:

FregServer进程,获取ServiceManager代理对象_第1张图片


BpBinder代理对象被保存在BpRefBase类的成员变量mRemote中。


三、目前为止各对象的引用计数

BpServiceManager受弱指针控制,ProcessState受强指针控制,BpBinder受弱指针控制。

static void instantiate(){defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService());}
出了这个函数,sp<IServiceManager>的强引用计数为1,弱引用计数为1,指向了全局的变量。

sp<ProcessState>的强引用计数为1,弱引用计数为1,指向了全局的变量。

sp<IBinder>的强引用计数为1,弱引用计数为1,指向了刚刚new BpBinder(0),即FregServer进程的Binder代理对象。

因为如下代码:

BpRefBase::BpRefBase(const sp<IBinder>& o)    : mRemote(o.get()), mRefs(NULL), mState(0){    extendObjectLifetime(OBJECT_LIFETIME_WEAK);    if (mRemote) {        mRemote->incStrong(this);           // Removed on first IncStrong().        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.    }}

更多相关文章

  1. C语言函数以及函数的使用
  2. android 调用draw(canvas) 函数自动退出
  3. Xposed框架之函数Hook学习
  4. android XMl 解析神奇xstream 四: 将复杂的xml文件解析为对象
  5. Android:控件的对象修改控件的值
  6. android中去掉空格--trim函数
  7. Android三角函数
  8. ISurfaceComposer接口有13个成员函数
  9. Android jni系统变量、函数、接口定义汇总

随机推荐

  1. android 调用摄像头
  2. android manifest文件结构
  3. android 加密字符串
  4. Android版本名称、版本号、API level对应
  5. android manifest文件结构
  6. [Linux][Android] Analyzing Memory Usag
  7. Android实现Bitmap高斯模糊效果
  8. Android(安卓)ConstraintLayout
  9. Android(安卓)FragmentManager之beginTra
  10. android的线性布局