Binder进程间通讯

文章详细介绍了Android系统中Binder通讯机制的核心过程,包括ProcessState的创建,内核与用户空间的通讯,defaultServiceManager的获取,以及线程池的启动和加入。重点讲解了BpBinder的使用,以及如何通过ioctl与内核交互进行数据传输。

A. 建立通讯链路 

        以frameworks/av/media/mediaserver/main_mediaserver.cpp为例来说明Binder通讯机制;

int main(int argc __unused, char **argv __unused)
{
    // 省略部分代码;
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm(defaultServiceManager());
    ALOGI("ServiceManager: %p", sm.get());

    // 省略部分代码;
    ::android::hardware::configureRpcThreadpool(16, false);
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    ::android::hardware::joinRpcThreadpool();
}

1. ProcessState

        从代码中可以看出:

  • ProcessState::self()创建一个进程唯一的ProcessState实例,并且建立了内核与用户空间的通讯(mmap映射)。
  • Binder通讯的大小接近(小于)1M;
  • mThreadPoolSeq从1开始计数, mDriverFD保存“/dev/binder”句柄资源;
#ifdef __ANDROID_VNDK__
const char* kDefaultDriver = "/dev/vndbinder";
#else
const char* kDefaultDriver = "/dev/binder";
#endif

sp<ProcessState> ProcessState::self()
{
    return init(kDefaultDriver, false /*requireDefault*/);
}

sp<ProcessState> ProcessState::init(const char* driver, bool requireDefault) {
     // 省略部分代码;
    [[clang::no_destroy]] static std::once_flag gProcessOnce;
    std::call_once(gProcessOnce, [&](){
        // 省略部分代码;

        // we must install these before instantiating the gProcess object,
        // otherwise this would race with creating it, and there could be the
        // possibility of an invalid gProcess object forked by another thread
        // before these are installed
        int ret = pthread_atfork(ProcessState::onFork, ProcessState::parentPostFork,
                                 ProcessState::childPostFork);
        LOG_ALWAYS_FATAL_IF(ret != 0, "pthread_atfork error %s", strerror(ret));

        std::lock_guard<std::mutex> l(gProcessMutex);
        gProcess = sp<ProcessState>::make(driver);
    });

    // 省略部分代码;

    verifyNotForked(gProcess->mForked);
    return gProcess;
}

#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
#define DEFAULT_MAX_BINDER_THREADS 15
ProcessState::ProcessState(const char* driver)
      : mDriverName(String8(driver)),
        mDriverFD(-1),
        mVMStart(MAP_FAILED),
        mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
        mThreadPoolSeq(1),
        mCallRestriction(CallRestriction::NONE) {
    base::unique_fd opened = open_driver(driver);

    if (opened.ok()) {

        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
                        opened.get(), 0);
        // 省略部分代码;
    }

    // 省略部分代码;

    if (opened.ok()) {
        mDriverFD = opened.release();
    }
}

2. defaultServiceManager

        这段代码位于:frameworks/native/libs/binder/IServiceManager.cpp,从代码上看返回一个IServiceManager接口实例,并且这个实例对于一个进程来说也是唯一的(gDefaultServiceManager);但要关注下几个细节;

using AidlServiceManager = android::os::IServiceManager;
static sp<IServiceManager> gDefaultServiceManager;

sp<IServiceManager> defaultServiceManager()
{
    std::call_once(gSmOnce, []() {
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
        /* wait for service manager */ {
        // 省略部分代码;

        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
            ★ sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            if (sm == nullptr) {
                ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
                sleep(1);
            }
        }

        gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
    });

    return gDefaultServiceManager;
}

2.1 getContextObject

        返回一个BpBinder实例;

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    sp<IBinder> context = getStrongProxyForHandle(0);

    // 省略部分代码;

    return context;
}

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = nullptr;
        e.refs = nullptr;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return nullptr;
    }
  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值