您的位置:首页 > 其它

FregServer进程,获取ServiceManager代理对象

2014-05-16 10:32 267 查看
本文参考《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(H***E_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(H***E_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打开设备文件,在/article/2587621.html这盘文章中已经讲解了驱动层的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) {//第二次为true
restart:
        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,参考博客/article/2587632.html,此时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());//返回NULL
		
		if (intr == NULL) {                
			intr = new BpServiceManager(obj);  //创建了Service Manager代理对象                                      
		}                                          
	}
	return intr;                                  
}
参数obj指向一个Binder代理对象,即一个BpBinder对象,它的成员函数queryLocalInterface的返回值为NULL。因此,最后会创建一个Service Manager代理对象,即一个BpServiceManger对象,并且将它的IServiceManager接口返回给调用者。
uml类图如下:



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.
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: