安卓系统Binder通信和系统服务管理

2 篇文章 0 订阅
2 篇文章 0 订阅

一、概述

Binder 是Android 系统提供的一种基于C/S架构体系的IPC机制。安卓系统通过ServiceManager管理系统服务器。服务提供者通可以通过Binder通信向ServiceManager注册服务器,而Client可以向ServiceManager查询服务,并且获取自己需要的服务器的handle,然后通过Binder调用自己需要服务器。架构如下:

二、Server如何通过Binder与ServiceManager通信

        我们以MediaServer为例,去看Server怎么与ServiceManager通信。MediaServer进程中驻留的服务有:MediaPlayService、CameraService、AudioPolicyService等服务器,可以在安卓系统代码中搜索到MediaServer的代码:Main_MediaServer.cpp如下:

1、获取ProcessState实例

代码通过ProcessState::self()获取一个ProcessState实例,函数的重要调用流如下,可以根据调用流自己跟一下代码:

调用流程(一层缩进一次函数调用,同一层缩进在同一个函数中):

ProcessState::self()

    ==> ProcessState::ProcessState()

        ==> open_driver()

            ==>int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);//打开binder设备驱动

        ==> mmap(0, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0)//通过mmap,驱动会分配一个内存,映射到用户空间

可以看出,ProcesstState:self打开了Binder驱动文件:"/dev/binder",并且通过mmap映射一段内存到用户空间。

2、获取ISericeManager与ServiceManager通信

通过defaultServiceManager(),获取ISericeManager对象,以便与ServiceManager通信。

调用流程:

defaultServiceManager()
    ==> ProcessState::self()->getContextObject()
        ==> getStrongProxyForHandle(0) //参数handle为0,0是ServiceManager的handle
            ==> BpHwBinder(handle)  //创建一个BpBinder
        ==>  interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
            ==> asInterface(obj);//生成一个IServiceManager,转入上面生成的BpBinder
                ==> new BpServiceManager(obj)//通过宏:IMPLEMENT_META_INTERFACE ,obj为上面生成的BpBinder,最终存于BpServiceManager的变量mRemote
                    ==> new BpInterface(obj)
                        ==> new BpRefBase(obj):mRemote(o.get()), mRefs(NULL), mState(0)

      通过调用,创建了一个BpBinder,并且用这个BpBinder生成了一个BpServiceManager,BpServiceManager有一个mRemote变量存放上面生成的BpBinder。BpServiceManager实现了ISericeManager接口。

他们的族谱如下图:

所以,通过defaultServiceManager(),可以得到以下两个对象:

  • 有一个BpBinder对象,它的Hanlel值为0,指向ServiceManager
  • 有一个BpServiceManager对包,它有一个mRemote值,是上面的BpBinder.

为什么要有上面两上对象呢?这两个对象又有何作用?

  • BpServiceManager对象主要实现与ServiceManager通信的业务逻辑,函数包括:getService()、addService()、checkService()、listServices()
  • BpBinder对象主要实现通信逻辑,函数包括:transact()

3、注册MediaPlayerService

 

上面函数重要调用流程如下:

defaultServiceManager()//为单例设计模式,直接返回上面的生成的BpServiceManager。
    ==> BpServiceManager::addService() 
        ==> remode() // 返回mRemote,即使BpBinder
        ==>BpHwBinder::transact()
            ==>IPCThreadState::self()->transact(mHandle, code, data, reply, flags);

 

(1)defaultServiceManager

defaultServiceManager()为单例设计模式,直接返回上面的生成的BpServiceManager。

(2) BpServiceManager::addService()

业务层逻辑,添加服务到SerivceManager,打包数据并调用BpHwBinder::transact()

 

(3)BpHwBinder::transact()

通信层逻辑,实现IPC通信,实际调用IPCThreadState::self() -> transact()

 

(4)IPCThreadState::self() -> transact()

IPCThreadState真实通信业务的承担者

IPCThreadState::self()作用:创建一个线程,并且创建一个IPCThreadState对象,作为线程的TLS:Thread Local Storage(线程本地空间,线程之间互相不共享,通过pthread_setspecific(gTLS, this)和pthread_getspecific(k)来获取和设置)。

每个线程都有一个IPCThreadState,每一个IPCThreadState都有一个mIn和mOunt,mIn用于接收自来Binder设备的数据,mOunt用于存储发往Binder设备的数据

调用流程:

IPCThreadState::self() -> transact()
    ==>IPCThreadState::self()
        ==>pthread_key_create(&gTLS, threadDestructor)//创建线程TLS空间
        ==>new IPCThreadState()//创建IPCThreadState对象
            ==> pthread_setspecific(gTLS, this);
            ==>mIn.setDataCapacity(256);
            ==> mOut.setDataCapacity(256);
    ==>IPCThreadState -> transact()
        ==>writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
            ==>mOut.writeInt32(cmd);
            ==>mOut.write(&tr, sizeof(tr));
    ==> waitForResponse(reply);
        ==>talkWithDriver();//与驱备沟通,实现读写和作用
            ==>ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) //通守ioctl对"/dev/binder"操作,实现binder读写通信

4、创建一个子线程与Binder通信

main_mediaserver.cpp中main函数调用:ProcessState::self()->startThreadPool();来创建一个子线程与Binder通信。

调用流程:

ProcessState::self()->startThreadPool();
    ==>	spawnPooledThread()
        ==>sp<Thread> t = new PoolThread(isMain);
        ==>t->run(name.string());
            ==>PoolThread::threadLoop()
                ==>IPCThreadState::self()->joinThreadPool(mIsMain);
                    ==>getAndExecuteCommand()//在while循环中被调用
                        ==>talkWithDriver()

5、主线程自己通Binder通信

main_mediaserver.cpp中main函数调用:IPCThreadState::self()->joinThreadPool(mIsMain);

三、Server小结:

 

 

  • MediaServer有四个服务:AudioFlinger、MediaPlayerService、CameraService和AudioPolicyService。
  • 通过调用PorcessState::self()打开binder设备驱动/dev/binder并通过通过mmap,驱动会分配一个内存,映射到用户空间。
  • 通过defaulteServiceManager(),创建一个BpBinder用于处理通信逻辑,生成一个BpServiceManager,用于处理业务逻辑。
  • 在各个Service的instantiate()函数中,创建服务并调用BpServiceManager的addService函数,与ServiceManager通信,注册服务
  • 创建一个子线程,在子线程和主线程中,轮询Binder设备通信

 

四、ServiceManager

 

(1)binder_open:打印驱动设备(“/dev/binder”)

调用流程:

binder_open()
    ==> open(driver, O_RDWR | O_CLOEXEC)
    ==> ioctl(bs->fd, BINDER_VERSION, &vers)
    ==>mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

 

(2) binder_become_context_manager()设置handle为0

==> ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);

(3) binder_loop(bs, svcmgr_handler):处理binder设备业务

binder_loop()
    ==> binder_parse()//通信逻辑
        ==>svcmgr_handler()//SerivceManager的业务逻辑:添加get\check\add\list service
        ==>binder_send_reply()

(4)关于注册服务调用流程:

do_add_service()

    ==> svc_can_register() // 判断是否有权限注册

    ==>find_svc () //查找是否已经存在服务

    ==> si->next = svclist; svclist =si; //添加到链表

    ==> binder_link_to_death //服务退出处理

 

ServiceManager存在意义:

  • 集中管理系统内的所有服务,权限管控
  • 通过名字查找服务,类似DNS
  • 使client更容易获取服务器的状态:生老病死

五、MediaPlayerService

1、MediaPlayerService的类继承家谱图

 

BnInterface继承了业务逻辑类(IMediaPlayerService)和通信逻辑类(BBinder)

 

 

类定义时,业务逻辑部分使用模板类,作用时方便切换不同业务逻辑。

 

2、MediaPlayerService如何提供服务

(1)client通过ServiceManger获取MediaPlayerService

IMediaDeathNotifier::getMediaPlayerService()
{
    ALOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService == 0) {
        //获取ServiceManger的BpBinder
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            //通过ServiceManger获取MediaPlayerService的BpBinder
            binder = sm->getService(String16("media.player"));
            if (binder != 0) {
                break;
            }
            ALOGW("Media player service not published, waiting...");
            usleep(500000); // 0.5 s
        } while (true);

        if (sDeathNotifier == NULL) {
            sDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(sDeathNotifier);
        //interface_cast把binder转换为BpMediaPlayerService
        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;
}

(2)MediaPlayerService如何提供服务

MediaPlayerService给Client提供服务的具体逻辑如下:

 

MediaPlayerService服务驻留在MediaServer进程中,上面已经介绍了,MediaServer进程通过两个线程,调用IPCThreadState::self()->joinThreadPool(mIsMain)接收Binder信息。

MediaPlayerService服务如何给client提供服务呢?

调用流:

==>IPCThreadState::self()->joinThreadPool(mIsMain);
    ==>IPCThreadState::getAndExecuteCommand
        ==>talkWithDriver();//通过Binder驱动获取
        ==>executeCommand() //运行服务指令,假设此如为BR_TRANSACTION
            ==>BnMediaPlayerService::onTransact()//如BnMediaPlayerService通过继承了

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值