ServiceManager总结

      最近在看Binder相关的东西,暂时的总结下。

      1. 在Android启动过程

           Android是基于linux的,所以Android的首先启动linux系统(bootloader和kernel),Init进程是第一个启动的用户进程,启动时会解   析放在设备根目录下的init.rc文件。该文件包含一些系统初始化配置和需要启动的一些守护进程。这些进程都包括:ueventd         console  adbd  servicemanager vold  netd  debuggerd   ril-deamon   surfaceflinger  zygote  drm   media  bootanim   dbus bluetoothd   installd   flash_recovery  racoon。都是一些很重要的进程。servicemanager就在其中.

      2. 启动servciemanager

            servciemanager的入口在frameworks/base/cmds/servicemanager/service_manager.c

int main(int argc, char **argv)
{
    struct binder_state *bs;
    void *svcmgr = BINDER_SERVICE_MANAGER;

    bs = binder_open(128*1024);

    if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    svcmgr_handle = svcmgr;
    binder_loop(bs, svcmgr_handler);
    return 0;
}
          binder_state代表binder驱动的状态,包括binder驱动文件描述符,映射到进程空间的起始地址和映射内存的大小,定义在 frameworks/base/cmds/servicemanager/binder.c

        BINDER_SERVICE_MANAGER是一个宏定义,((void*) 0) ,就是0,表示servicemanager的句柄为0

        binder_open的实现在frameworks/base/cmds/servicemanager/binder.c     

struct binder_state *binder_open(unsigned mapsize)
{
    struct binder_state *bs;

    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return 0;
    }

    bs->fd = open("/dev/binder", O_RDWR);
    if (bs->fd < 0) {
        fprintf(stderr,"binder: cannot open device (%s)\n",
                strerror(errno));
        goto fail_open;
    }

    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    if (bs->mapped == MAP_FAILED) {
        fprintf(stderr,"binder: cannot map device (%s)\n",
                strerror(errno));
        goto fail_map;
    }

        /* TODO: check version */

    return bs;

fail_map:
    close(bs->fd);
fail_open:
    free(bs);
    return 0;
}
       给binder_state分配内存空间,调用系统调用打开binder驱动文件,并映射到进程空间中,大小为128K。binder驱动的状态保存在binder_state中。

     binder_become_context_manager通过系统调用ioctl告诉binder驱动ServiceManager是守护进程

int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
       命令码BINDER_SET_CONTEXT_MGR

#define BINDER_SET_CONTEXT_MGR      _IOW('b', 7, int)  
       最后ServiceManager进程入无限循环中,等待client进程请求

void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    unsigned readbuf[32];

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;
    
    readbuf[0] = BC_ENTER_LOOPER;
    binder_write(bs, readbuf, sizeof(unsigned));

    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (unsigned) readbuf;

        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }

        res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
        if (res == 0) {
            ALOGE("binder_loop: unexpected reply?!\n");
            break;
        }
        if (res < 0) {
            ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
            break;
        }
    }
}
         binder_write() 就是通过ioctl系统调用把命令码包装在binder_write_read结构体中并传递给binder驱动。命令码BC_ENTER_LOOPER就是告诉binder驱动进入到循环中,保存在write_buffer中。

         在for循环中又进行了一次ioctl操作,此时binder驱动会进入一个等待状态。直接有請求才会唤醒,执行完相关的操作后,由binder_parse进行解析操作的结果。

    此总结是参考http://blog.csdn.net/luoshengyang/article/details/6621566。

       3. 如何获取ServiceManager
           在native层中通过调用defaultServiceManager(),它的实现在frameworks/base/libs/binder/IServiceManager.cpp。它的实现是单例,也就是       每个进程只有一个实例。

if (gDefaultServiceManager != NULL) return gDefaultServiceManager;    
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        if (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
        }
    }
          首先来看ProcessState::self()->getContextObject(NULL)。 ProcessState也是一个单例模式,在它的构造函数中会调用open_binder() 打开binder驱动,文件描述符保存在变量mDriverFD中。再来看getContextObject(NULL),它调用getStrongProxyForHandle(0),接着调用lookupHandleLocked(0)。而loopupHandlerLocked()是从Vector<handle_entry>mHandleToObject;中获取的。此时mHandleToObject还是空,loopupHandleLocked()会往mHandleToObject中插入一个空的handle_entry结构体。并返回。

       回到loopupHandleLocked()中,它判断返回的handle_entry中的IBinder为NULL,它会创建一个BpBinder(0)并返回。

Vector<handle_entry>mHandleToObject;

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
    return getStrongProxyForHandle(0);
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    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)) {
            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // 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);
            e->refs->decWeak(this);
        }
    }

    return result;
}

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        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);
}
        在创建BpBinder时,会初初始化IPCThreadState和ProcessState对象,在ProcessState的构造函数中,会打开binder驱动文件,映射到进程空间中。这时就不详细分析了,现在的结果是interface_cast<IServiceManager>(new BpBinder(0));

        来看一下和binder相关的类继承关系:

                                                   <---  BpRefBase

                                 RefBase  <--  IBinder    <--   BpBinder

                                                                          <--    BBinder

                                                   <--  IInterface  <--  BnInterface(还继承IXXX和BBinder)

                                                                             <--  BpInterface (还继承IXXX和BpRefBase)

       接着再来看一下interface_cast<IServiceManager>

       IServiceManager继承自IInterface,interface_cast的声明如下 

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
      而IIterface中还定义了如下两个宏

#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const android::String16 descriptor;                          \
    static android::sp<I##INTERFACE> asInterface(                       \
            const android::sp<android::IBinder>& obj);                  \
    virtual const android::String16& getInterfaceDescriptor() const;    \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();                                            \
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const android::String16 I##INTERFACE::descriptor(NAME);             \
    const android::String16&                                            \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
            const android::sp<android::IBinder>& obj)                   \
    {                                                                   \
        android::sp<I##INTERFACE> intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \
         上两段代码中所有出现的INTERFACE都会替换为ServiceManager,现在只看adInterface,最终会变为

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());
		if (intr == NULL) {                
			intr = new BpServiceManager(obj);                                        
		}                                          
	}
	return intr;                                  
}   
         调用obj.queryLocalInterface(),此obj就是上面创建的BpBinder对象,而queryLocalInterrface的在其父类IBinder中声明的,实现为

sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
{
    return NULL;
}
          至此,defaultServiceManager()分析完毕,最终返回的是BpServiceManager对象。由于ServiceManger是单例模式,所以以后再调用defaultServiceManger()时直接返回的就是BpServiceManger对象的引用。


你可能感兴趣的:(ServiceManager总结)