【笔记】 Binder

1.基本前提

0.每个进程 有且必有一个ProcessState 对象

1.binder 通信用于跨进程通信,而通信具体的操作区域是在内核空间,即(“用户空间进程client_A” <-----> 内核空间 <----> “用户空间进程Server_B”)

2.上图可知,不管 client 与内核空间 还是 server 与内核空间 的交互,都是  进程client_A的ProcessState 对象与内核交互  或者 进程server_B的ProcessState 对象与内核交互,  都依赖于ProcessState 对象。

3.每个进程有且只有一个 ProcessState 对象,这是通过单例模式来保证的;一个进程多个线程,但是每个线程一个IPCThreadState对象,也是单例模式确保的。

4.binder 驱动层的每一个 binder_proc 结构体都与用户空间的一个用于 binder 通信的进程一一对应。

5.注意内核中第一个是“binder_procs”,是全局链表,是serviceManager 初始化时创建。 

2.ServiceManager

 ServiceManager 的作用很简单就是提供了client端的查询服务和serer 端注册服务的功能

Service Manager的入口位于service_manager.c文件中的main函数:

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)) {
        LOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
 
    svcmgr_handle = svcmgr;
    binder_loop(bs, svcmgr_handler);
    return 0;
}

  2.1 SM : 打开驱动

            1.初始化 ServiceManager进程的ProcessState对象,调用open_driver 读取binder驱动节点/dev/binder,节点读取fd放在ProcessState.mDriverFD中;

            2.设置此进程的设置binder线程数量最大为 15

            3.打开驱动设备 , 创建全局链表 binder_procs

  2.2   SM:设为守护进程

            将自己当前进程信息保存到 binder_procs 链表,句柄为“0”

  2.3   SM:开启for 循环

           最后开启 loop 不断的处理共享内存中的数据,并处理 BR_xxx 命令(ioctl 的命令,BR 可以理解为 binder reply 驱动处理完的响应)

 

3.client端获取ServiceManager 服务

Service Manager在Binder机制中既是守护进程,也是Server角色:

     1.普通的Server来说,Client如果想要获得Server的远程接口,必须通过Service Manager远程接口提供的getService接口来获得,这本身就是一个使用Binder机制来进行进程间通信的过程;

     2.Service Manager这个Server来说,Client如果想要获得Service Manager远程接口,却不必通过进程间通信机制来获得,因为Service Manager远程接口是一个特殊的Binder引用,它的引用句柄一定是0;

     3.service调用SM.addService 与 client 端调用SM.getService  时角色是一样的,都是Binder 里的client 端(此时的ServiceManager才是Server端),所以调用defaultServiceManager 时,获取到的都是client端的BinderProxy 对象。

     获取Service Manager远程接口的函数是defaultServiceManager:

frameworks/base/include/binder/IServiceManager.h

sp<IServiceManager> defaultServiceManager();


实际定义在:

sp<IServiceManager> defaultServiceManager()
{
 
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
 
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        if (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
        }
    }
 
    return gDefaultServiceManager;
}

 创建defaultManagerService 对象的语句可以简化为获取一个IServiceManager.cpp中定义的BpServiceManager 类:

gDefaultServiceManager = new BpServiceManager(new BpBinder(0));

  Service Manager远程接口实际上就是一个BpServiceManager对象,包含了一个句柄值为0的Binder引用。

  3.1 BpServiceManager

class BpServiceManager : public BpInterface<IServiceManager>
{
... ...

    virtual sp<IBinder> getService(const String16& name) const
    {
       ... ...
            sp<IBinder> svc = checkService(name);
       ... ...;
    }

    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,
            bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

    virtual Vector<String16> listServices()
    {
        ... ...
    }
}

 现在看一下如下这个类图:

总结一下:

1. IServiceManager类继承了IInterface类,而IInterface类和BpRefBase类又分别继承了RefBase类

2.BpRefBase类中,有一个成员变量mRemote,它的类型是IBinder*,实现类为BpBinder,它表示一个Binder引用,引用句柄值保存在BpBinder类的mHandle成员变量中

3.BpBinder类通过IPCThreadState类来和Binder驱动程序并互,而IPCThreadState又通过它的成员变量mProcess来打开/dev/binder设备文件,mProcess成员变量的类型为ProcessState。ProcessState类打开设备/dev/binder之后,将打开文件描述符保存在mDriverFD成员变量中,以供后续使用。

这个图简单理解为:BpServiceManager中调用"mRemote->transact" 实际上是BpBinder通过IPCThreadState类来和Binder驱动程序并互。

所以简单理解为:

defaultManagerService.addService() 

 ---> BpServiceManager(BpBinder(0)).addService()

 ---> (BpBinder(0))mRemote->transact(ADD_SERVICE_TRANSACTION, data, &reply)

调用default Manager Service实际上获取到的是一个IServiceManager.cpp 中的BpServiceManager对象,此BpServiceManager中包含一个代表ServiceManager 的BpBinder对象,

4.Service注册服务

1.注册服务的过程,实际就是binder 通信的过程:

   1.service_A 进程 获取到代表service_manager 的BpBinder(0)

   2.在service_A 进程 中,调用(BpBinder(0))remote->tansact ,发送ADD_SERVICE_TRANSACTION 消息,且调用的线程.waitForResponse ,进入等待;

   3.ServiceManager 创建服务端进程 binder_node 信息并插入到 binder_procs 链表中。

   4.ServiceManager 进程发送 BR_REPLY 命令唤醒等待的线程,通知注册成功,service开始运行;

总结一下 3 和 4 :

client端通过ServiceManager获取service   和 service 通过ServiceManager 注册service  本质是一样的,都是与作为Server 端的ServiceManager进行binder通信的过程:

1.client端 是通过 通过defaultServiceManager 获取到包含BpBinder(0)的BpServiceManager 对象,BpBinder(0)通过此线程的IPCThreadState 与/dev/binder 进行交互 <---> ServiceManager 作为Server端binder_loop处理信息,返回对于service 的binder_proc 等信息;

2.service 是通过 通过defaultServiceManager 获取到包含BpBinder(0)的BpServiceManager 对象,BpBinder(0)通过此线程的IPCThreadState 与/dev/binder 进行交互 <--->ServiceManager 作为Server端binder_loop处理信息,将新注册的service 的binder_proc 信息插入binder_procs 全局链表中;

5.Service接收消息

 先看一个Service 的定义:

class MountService extends IMountService.Stub
        implements INativeDaemonConnectorCallbacks, Watchdog.Monitor 



... ...


public class PackageManagerService extends IPackageManager.Stub 

Service都是继承IXXXXService.stub 类

有此类图可以看出stub类其实是继承Binder 类,所以Service 可以看成一个Binder 对象:

binder 

猜你喜欢

转载自blog.csdn.net/pirionFordring/article/details/84112344