ServiceManager总结

来源:互联网 发布:最后的战役 知乎 编辑:程序博客网 时间:2024/05/21 11:52

      最近在看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对象的引用。


原创粉丝点击