Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)

摘要:本节主要来讲解Android10.0 Native层HIDL服务的注册原理

阅读本文大约需要花费23分钟。

文章首发微信公众号:IngresGe

专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

[Android取经之路] 系列文章:

《系统启动篇》

  1. Android系统架构
  2. Android是怎么启动的
  3. Android 10.0系统启动之init进程
  4. Android10.0系统启动之Zygote进程
  5. Android 10.0 系统启动之SystemServer进程
  6. Android 10.0 系统服务之ActivityMnagerService
  7. Android10.0系统启动之Launcher(桌面)启动流程
  8. Android10.0应用进程创建过程以及Zygote的fork流程
  9. Android 10.0 PackageManagerService(一)工作原理及启动流程
  10. Android 10.0 PackageManagerService(二)权限扫描
  11. Android 10.0 PackageManagerService(三)APK扫描
  12. Android 10.0 PackageManagerService(四)APK安装流程

《日志系统篇》

  1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
  2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
  3. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
  4. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​

《Binder通信原理》

  1. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
  2. Android10.0 Binder通信原理(二)-Binder入门篇
  3. Android10.0 Binder通信原理(三)-ServiceManager篇
  4. Android10.0 Binder通信原理(四)-Native-C\C++实例分析
  5. Android10.0 Binder通信原理(五)-Binder驱动分析
  6. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
  7. Android10.0 Binder通信原理(七)-Framework binder示例
  8. Android10.0 Binder通信原理(八)-Framework层分析
  9. Android10.0 Binder通信原理(九)-AIDL Binder示例
  10. Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
  11. Android10.0 Binder通信原理(十一)-Binder总结

  《HwBinder通信原理》

  1. HwBinder入门篇-Android10.0 HwBinder通信原理(一)
  2.  HIDL详解-Android10.0 HwBinder通信原理(二)
  3. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
  4. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
  5. HwServiceManager篇-Android10.0 HwBinder通信原理(五)
  6. Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
  7. Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
  8. JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)

​​​​​​​

1.概述

    在上一节中,我们知道了HwServiceManager的启动过程,注册、获取服务的细节处理。服务的信息都存在于一个mServiceMap的map容器中。

 mServiceMap对应的key为package interface 名称,例如"[email protected]::IServiceManager", 对应的value为一个PackageInterfaceMap结构体,其中包含了lookup()、insertService()等方法,

service的对象最终被插入到 InstanceMap 这个map容器中。

       前面我们已经写了一个HIDL实例,来展示了Native层的服务注册和获取调用流程,但是Native层的服务注册、获取流程是如何实现的,现在还不清楚。

这一节,我们深度分析Native层的HAL服务的注册和获取。

 

2. Native层的HwBinder架构

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第1张图片

 

3. 重要类分析

 在真正看代码前,需要先了解两个类-ProcessState和IPCThreadState 这两个很重要类的概念。

 

3.1 ProcessState

  ProcessState从字面意思可以理解,表示是“进程状态”,代表了这个进程的行为,Android中,每个进程都是独立的,所以每个进程都要有一个“进程状态”--ProcessState.

在Binder通信机制中,ProcessState使用了单例模式,即一个进程只有个ProcessState对象,一个进程中有很多个线程,不能每个线程都来new一个新的ProcessState(),采用单例模式后,每个线程都可以使用同一个ProcessState来和Binder驱动通信。

ProcessState作为进程状态的记录器,主要用来打开Binder驱动获取句柄,mmap申请一块(1M-8K)的内存空间,设置Binder线程最大个数。

 

3.2 IPCThreadState

  IPCThreadState从字面意思可以理解,表示是“进程间通信的线程状态”,有了进程状态后,自然需要有线程状态。

  ProcessState代表了进程,IPCThreadState代表了线程。Android系统中有很多进程,进程间相互隔离,每个进程内部又有很多线程,线程之间也是相互独立的。所以说一个进程会存在很多个线程,每个线程都有自己的“线程状态”--IPCThreadState对象.这个对象存储在线程的本地存储区(TLS:Thread local storage)中,每个线程都拥有自己的TLS,并且是私有空间,线程之间不会共享。

  IPCThreadState对象根据key:gTLS去进行存储。通过pthread_getspecific/pthread_setspecific函数可以获取/设置这些空间中的内容。

  IPCThreadState负责与Binder驱动进行数据交互。

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第2张图片

 

3.3 BpHwBinder

   BpHwBinder 展开后就是Binder Proxy,也就是Binder代理的含义。BpHwBinder 是客户端用来与服务交互的代理类,负责实现跨进程传输的传输机制,不关心具体的传输内容。通信功能由其它类和函数实现,但由于这些类和函数被BpHwBinder代理,所以客户端需要通过BpHwBinder来发送Binder通信数据。

     

3.4 BHwBinder

   BHwBinder代表服务端,可以理解为服务的Binder实体,当服务端从Binder驱动中读取到数据后,由BHwBinder类进行处理。

 

4. IDemo的服务注册

 IDemo的HIDL服务注册流程如下图所示:

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第3张图片

 

4.1 调用栈如下

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第4张图片

 

4.2 main()

[\vendor\ingres\interfaces\demo\1.0\default\Service.cpp]
int main() {
    configureRpcThreadpool(4, true);    //和"dev/hwbinder" 进行通信,设置最大的线程个数为4

    Demo demo;
    auto status = demo.registerAsService(); //注册服务,参考[4.3]
    CHECK_EQ(status, android::OK) << "Failed to register demo HAL implementation";

    joinRpcThreadpool();    //把当前线程加入到线程池
    return 0;
}

IDemo的服务注册流程分为以下几步:

1.获得ProcessState实例对象,与"/dev/hwbinder"进行通信,设置最大的线程个数为4

2.获取Demo服务对象

3.调用registerAsService注册IDemo服务

4.把当前线程加入到线程池

服务注册,主要的入口就是 registerAsService(),下面我们从registerAsService()进一步分析

 

4.3 registerAsService()

  开始HIDL服务注册,DemoAll.cpp 在编译的时候生成,源对象为IDemo.hal

[\out\soong\.intermediates\vendor\ingres\interfaces\demo\1.0\[email protected]_genc++\gen\vendor\ingres\demo\1.0\DemoAll.cpp]
DemoAll.cpp 在编译的时候生成,源对象为IDemo.hal
__attribute__ ((warn_unused_result))::android::status_t registerAsService(const std::string &serviceName="default");

::android::status_t IDemo::registerAsService(const std::string &serviceName) {
     //默认的serviceName是default,参考[4.4]
    return ::android::hardware::details::registerAsServiceInternal(this, serviceName); 
}

4.4 registerAsServiceInternal()

[/system/libhidl/transport/ServiceManagement.cpp]
status_t registerAsServiceInternal(const sp& service, const std::string& name) {
    if (service == nullptr) {
        return UNEXPECTED_NULL;
    }
    
    //1.获取HwServiceManager代理对象:BpHwServiceManager,fromBinder最终为 new BpHwServiceManager(new BpHwBinder(0))
    //参考[4.5]
    sp sm = defaultServiceManager1_2();
    if (sm == nullptr) {
        return INVALID_OPERATION;
    }

    bool registered = false;
    Return ret = service->interfaceChain([&](const auto& chain) {
        //2.通过HwServiceManager代理对象BpHwServiceManager进行服务的注册
        //参考[4.6]
        registered = sm->addWithChain(name.c_str(), service, chain).withDefault(false); 
    });

    if (!ret.isOk()) {
        LOG(ERROR) << "Could not retrieve interface chain: " << ret.description();
    }

    if (registered) {
        onRegistrationImpl(getDescriptor(service.get()), name);
    }

    return registered ? OK : UNKNOWN_ERROR;
}

核心步骤:

1.拿到HwServiceManager的代理对象 BpHwServiceManager

2.通过该代理对象,进行HAL服务的注册

 

4.5sp defaultServiceManager1_2()

  defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager

[/system/libhidl/transport/ServiceManagement.cpp]
sp defaultServiceManager1_2() {
    using android::hidl::manager::V1_2::BnHwServiceManager;
    using android::hidl::manager::V1_2::BpHwServiceManager;

    static std::mutex gDefaultServiceManagerLock;
    static sp gDefaultServiceManager;

    {
        std::lock_guard _l(gDefaultServiceManagerLock);
        if (gDefaultServiceManager != nullptr) {
            return gDefaultServiceManager;
        }
        //1.检查hwbinder的节点是否存在,如果不存在说明不支持hwbinder
        if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
            // HwBinder not available on this device or not accessible to
            // this process.
            return nullptr;
        }
        //2.等待属性"hwservicemanager.ready" 变为true,表明hwservicemanager已经启动好
        waitForHwServiceManager();

        while (gDefaultServiceManager == nullptr) {
            //3.拿到HwServiceManager的代理对象
            gDefaultServiceManager =
                fromBinder(
                    ProcessState::self()->getContextObject(nullptr));
            if (gDefaultServiceManager == nullptr) {
                LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";
                sleep(1);
            }
        }
    }

    return gDefaultServiceManager;
}

4.5.1 ProcessState::getContextObject

[/system/libhwbinder/ProcessState.cpp]
sp ProcessState::getContextObject(const sp& /*caller*/)
{
    return getStrongProxyForHandle(0);  //传入handle = 0, HwServiceManager的handle就为0
}

 获取一个BpHwBinder的对象,即当Service向HwServiceManager进行注册时,Service变成了Client,HwServiceManager变成了Server,需要先把Service 转换成一个BpHwBinder对象,作为Binder代理进行通信

sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {
        IBinder* b = e->binder;
        //handle = 0传入的binder在lookupHandleLocked()中赋值为nullptr
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            b = new BpHwBinder(handle);  //binder对象为new BpHwBinder(0)
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }
    return result;
}

4.5.2 fromBinder()

  根据BpHwBinder 这个远程对象,拿到HwServiceManager的对象,这里是远程对象,所以返回一个BpHwServiceManager 对象。

  BpHwBinder负责数据传输,而BpHwServiceManager服务数据业务,业务数据在BpHwServiceManager层打包好后,转交给BpHwBinder发送。

[/system/libhidl/transport/ServiceManagement.cpp]
template 
sp fromBinder(const sp& binderIface) {
    using ::android::hidl::base::V1_0::IBase;
    using ::android::hidl::base::V1_0::BnHwBase;

    if (binderIface.get() == nullptr) {
        return nullptr;
    }
    //这里传入的binderIface 其中的Binder对象为 new BpHwBinder(0),这是一个remote的Binder,这里的ProxyType是BpHwServiceManager  所以返回一个new BpHwServiceManager()
    if (binderIface->localBinder() == nullptr) {
        return new ProxyType(binderIface);
    }
    sp base = static_cast(binderIface.get())->getImpl();
    if (details::canCastInterface(base.get(), IType::descriptor)) {
        StubType* stub = static_cast(binderIface.get());
        return stub->getImpl();
    } else {
        return nullptr;
    }
}

BpHwServiceManager的类继承关系如下图所示:

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第5张图片

4.6 BpHwServiceManager::addWithChain()

[\out\soong\.intermediates\system\libhidl\transport\manager\1.2\[email protected]_genc++\gen\android\hidl\manager\1.2\ServiceManagerAll.cpp]
::android::hardware::Return BpHwServiceManager::addWithChain(const ::android::hardware::hidl_string& name, const ::android::sp<::android::hidl::base::V1_0::IBase>& service, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& chain){
   ::android::hardware::Return  _hidl_out = ::android::hidl::manager::V1_2::BpHwServiceManager::_hidl_addWithChain(this, this, name, service, chain); //调用_hidl_addWithChain()进行执行
    return _hidl_out;
}

_hidl_addWithChain的主要步骤如下:

1.准备两个Parcel结构-- _hidl_data,_hidl_reply

2.组装Parcel数据

3.写入RPC头信息"[email protected]::IServiceManager"

4.写入服务名称,如果没有配置的话,name为"default"

5.写入服务的实体对象--new Demo()

6.调用remote的transact,发送 12 /* addWithChain */ 的命令进行服务的注册

7.得到返回的reply数据

::android::hardware::Return BpHwServiceManager::_hidl_addWithChain(::android::hardware::IInterface *_hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_string& name, const ::android::sp<::android::hidl::base::V1_0::IBase>& service, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& chain) {
    #ifdef __ANDROID_DEBUGGABLE__
    bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();
    const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();
    #else
    (void) _hidl_this_instrumentor;
    #endif // __ANDROID_DEBUGGABLE__
    ::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, "HIDL::IServiceManager::addWithChain::client");
    #ifdef __ANDROID_DEBUGGABLE__
    if (UNLIKELY(mEnableInstrumentation)) {
        std::vector _hidl_args;
        _hidl_args.push_back((void *)&name);
        _hidl_args.push_back((void *)&service);
        _hidl_args.push_back((void *)&chain);
        for (const auto &callback: mInstrumentationCallbacks) {
            callback(InstrumentationEvent::CLIENT_API_ENTRY, "android.hidl.manager", "1.2", "IServiceManager", "addWithChain", &_hidl_args);
        }
    }
    #endif // __ANDROID_DEBUGGABLE__

    ::android::hardware::Parcel _hidl_data;     //定义一个Parcel的data数据包
    ::android::hardware::Parcel _hidl_reply;    //定义一个Parcel的reply数据包
    ::android::status_t _hidl_err;
    ::android::hardware::Status _hidl_status;

    bool _hidl_out_success;

    //1.写入RPC头信息"[email protected]::IServiceManager"
    _hidl_err = _hidl_data.writeInterfaceToken(BpHwServiceManager::descriptor);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    size_t _hidl_name_parent;

    //2.写入服务名称,如果没有配置的话,name为"default"
    _hidl_err = _hidl_data.writeBuffer(&name, sizeof(name), &_hidl_name_parent);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    _hidl_err = ::android::hardware::writeEmbeddedToParcel(
            name,
            &_hidl_data,
            _hidl_name_parent,
            0 /* parentOffset */);

    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    if (service == nullptr) {
        _hidl_err = _hidl_data.writeStrongBinder(nullptr);
    } else {
        //3.根据传入的service,获取对应的hidl binder实体,把一个binder实体“打扁”并写入parcel,实体为 new Demo()
        ::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::getOrCreateCachedBinder(service.get());
        if (_hidl_binder.get() != nullptr) {
            _hidl_err = _hidl_data.writeStrongBinder(_hidl_binder);
        } else {
            _hidl_err = ::android::UNKNOWN_ERROR;
        }
    }
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    size_t _hidl_chain_parent;

    _hidl_err = _hidl_data.writeBuffer(&chain, sizeof(chain), &_hidl_chain_parent);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    size_t _hidl_chain_child;

    _hidl_err = ::android::hardware::writeEmbeddedToParcel(
            chain,
            &_hidl_data,
            _hidl_chain_parent,
            0 /* parentOffset */, &_hidl_chain_child);

    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    for (size_t _hidl_index_0 = 0; _hidl_index_0 < chain.size(); ++_hidl_index_0) {
        _hidl_err = ::android::hardware::writeEmbeddedToParcel(
                chain[_hidl_index_0],
                &_hidl_data,
                _hidl_chain_child,
                _hidl_index_0 * sizeof(::android::hardware::hidl_string));

        if (_hidl_err != ::android::OK) { goto _hidl_error; }

    }

    //4.启动一个线程池
    ::android::hardware::ProcessState::self()->startThreadPool();
    //5.调用BpHwBinder::transact(),asBinder转换过程,参考下图
    //_hidl_this 指的是 BpHwServiceManager,通过asBinder转换为传输层面的BpHwBinder对象,其实就是取出BpHwServiceManager的成员变量mRemote的值
    _hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(12 /* addWithChain */, _hidl_data, &_hidl_reply);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    //6.从_hidl_reply读取返回结果
    _hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    if (!_hidl_status.isOk()) { return _hidl_status; }

    _hidl_err = _hidl_reply.readBool(&_hidl_out_success);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    #ifdef __ANDROID_DEBUGGABLE__
    if (UNLIKELY(mEnableInstrumentation)) {
        std::vector _hidl_args;
        _hidl_args.push_back((void *)&_hidl_out_success);
        for (const auto &callback: mInstrumentationCallbacks) {
            callback(InstrumentationEvent::CLIENT_API_EXIT, "android.hidl.manager", "1.2", "IServiceManager", "addWithChain", &_hidl_args);
        }
    }
    #endif // __ANDROID_DEBUGGABLE__

    _hidl_status.setFromStatusT(_hidl_err);
    return ::android::hardware::Return(_hidl_out_success);

_hidl_error:
    _hidl_status.setFromStatusT(_hidl_err);
    return ::android::hardware::Return(_hidl_status);
}

asBinder的转换后,得到的对象是BpHwBinder,asBinder转换如下图所示:

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第6张图片

 

4.7 BpHwBinder::transact()

[/system/libhwbinder/BpHwBinder.cpp]
status_t BpHwBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback /*callback*/)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        //拿到IPCThreadState的对象,调用transact()执行
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

BpBinder::transact()就是调用IPCThreadState::self()->transact() 进行处理

 

4.7.1 IPCThreadState::transact()

[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    status_t err;

    flags |= TF_ACCEPT_FDS;

    ...
    //1.传输数据, 参考[4.7.2]
    err = writeTransactionData(BC_TRANSACTION_SG, flags, handle, code, data, nullptr);

    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }

    if ((flags & TF_ONE_WAY) == 0) {
        if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) {
            if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) {
                ALOGE("Process making non-oneway call but is restricted.");
                CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
                    ANDROID_LOG_ERROR);
            } else /* FATAL_IF_NOT_ONEWAY */ {
                LOG_ALWAYS_FATAL("Process may not make oneway calls.");
            }
        }

        ...
        //2.等待响应
        if (reply) {
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
        ...
    } else {
        //3.oneway,则不需要等待reply的场景
        err = waitForResponse(nullptr, nullptr);
    }

    return err;
}

IPCThreadState::transact()主要做了下面几步:

1. writeTransactionData() 组装一个 binder_transaction_data_sg 结构的数据,存入mOut中,mOut是一个Parcel的数据结构,处理的时候,前4个字节存入BC_XX 请求码,这里是BC_TRANSACTION,后面存入sizeof(binder_transaction_data_sg)长度的数据

2. waitForResponse() 和hwbinder进行通信,传送内容,等待响应

 

4.7.2 IPCThreadState::writeTransactionData()

[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    binder_transaction_data_sg tr_sg;
    /* Don't pass uninitialized stack data to a remote process */
    tr_sg.transaction_data.target.ptr = 0;
    tr_sg.transaction_data.target.handle = handle;
    tr_sg.transaction_data.code = code;
    tr_sg.transaction_data.flags = binderFlags;
    tr_sg.transaction_data.cookie = 0;
    tr_sg.transaction_data.sender_pid = 0;
    tr_sg.transaction_data.sender_euid = 0;

    const status_t err = data.errorCheck();
    if (err == NO_ERROR) {
        //把Parcel的数据转换到binder_transaction_data中
        tr_sg.transaction_data.data_size = data.ipcDataSize();
        // 这部分是待传递数据
        tr_sg.transaction_data.data.ptr.buffer = data.ipcData();
        // 这部分是扁平化的binder对象在数据中的具体位置
        tr_sg.transaction_data.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
        tr_sg.transaction_data.data.ptr.offsets = data.ipcObjects();
        tr_sg.buffers_size = data.ipcBufferSize();
    } else if (statusBuffer) {
        tr_sg.transaction_data.flags |= TF_STATUS_CODE;
        *statusBuffer = err;
        tr_sg.transaction_data.data_size = sizeof(status_t);
        tr_sg.transaction_data.data.ptr.buffer = reinterpret_cast(statusBuffer);
        tr_sg.transaction_data.offsets_size = 0;
        tr_sg.transaction_data.data.ptr.offsets = 0;
        tr_sg.buffers_size = 0;
    } else {
        return (mLastError = err);
    }

    //把组装好的binder_transaction_data_sg 写入mOut
    mOut.writeInt32(cmd);
    mOut.write(&tr_sg, sizeof(tr_sg));

    return NO_ERROR;
}

writeTransactionData() 主要就是把传入的Parcel数据,转换成 

binder_transaction_data_sg,写入mOut,用来与Binder驱动交互。其中

tr_sg.transaction_data.data.ptr.buffer 记录了Parcel传输的数据,

tr_sg.transaction_data.data.ptr.offsets "待传数据"中记录所有binder对象的具体位置。

 

4.7.3 IPCThreadState::waitForResponse()

  waitForResponse()里面是一个while(1)循环,可以处理多个命令,只有进入goto finish后,循环才退出。如果返回的cmd不在switch的case中,进入default,调用executeCommand()来单独执行这些cmd.

[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    uint32_t cmd;
    int32_t err;

    while (1) {
            //1.和hwbinder进行通信,把上面writeTransactionData()组装的mOut发给hwbinder,参考[4.7.4]
        if ((err=talkWithDriver()) < NO_ERROR) break;
        ...
            //2.读取hwbinder返回回来的cmd值
        cmd = (uint32_t)mIn.readInt32();
        ...

        switch (cmd) {
        case BR_TRANSACTION_COMPLETE:
            if (!reply && !acquireResult) goto finish;
            break;

        case BR_DEAD_REPLY:
            ...
            goto finish;

        case BR_FAILED_REPLY:
            ...
            goto finish;

        case BR_ACQUIRE_RESULT:
            ...
            goto finish;

        case BR_REPLY:
            ...
            goto finish;

        default:
                //3.执行cmd,参考[4.7.5]
            err = executeCommand(cmd);
            if (err != NO_ERROR) goto finish;
            break;
        }
    }

finish:
    if (err != NO_ERROR) {
        if (acquireResult) *acquireResult = err;
        if (reply) reply->setError(err);
        mLastError = err;
    }

    return err;
}

4.7.4 IPCThreadState::talkWithDriver()

  talkWithDriver()用来不停的和Binder驱动进行通信,ioctl()函数在传递BINDER_WRITE_READ语义时,既会使用“输入buffer”,也会使用“输出buffer”,所以IPCThreadState专门搞了两个Parcel类型的成员变量:mIn和mOut。mOut中的内容发出去,发送后的reply写进mIn。

  BINDER_WRITE_READ的命令发给Binder驱动后,HwServiceManager的epoll_wait()一直在等待事务处理,HwServiceManager从mRequests中取出原先注册的handleEvent处理,例如HwBinderCallback::handleEvent,HwServiceManager和hwbinder进行通信,取出BR_TRANSACTION的内容,最后调用到BnHwServiceManager::onTransact进行解析,根据之前传入的code=12,走入_hidl_addWithChain进行服务注册,接着把服务端的name和对象,插入到mServiceMap表中,最终把reply的数据发送出去,client在talkWithDriver()中填入mIn中,waitForResponse()进行最终的语义处理,发送出去。

[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    if (mProcess->mDriverFD <= 0) {
        return -EBADF;
    }

    binder_write_read bwr;

    // Is the read buffer empty?
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();

    //如果仍在读取输入缓冲区中剩余的数据,并且调用方已请求读取下一个数据,则不希望写入任何内容。
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

    bwr.write_size = outAvail;
    //1.把mOut的数据存入 write_buffer中
    bwr.write_buffer = (uintptr_t)mOut.data(); 

    // This is what we'll read.
    if (doReceive && needRead) {
        //接收数据缓冲区信息的填充。如果以后收到数据,就直接填在mIn中了
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (uintptr_t)mIn.data();
    } else {
        //没有收到数据时,把read置空,hwbinder只进行write处理
        bwr.read_size = 0;
        bwr.read_buffer = 0;
    }
    ...

    //当读缓冲和写缓冲都为空,则直接返回
    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;

    bwr.write_consumed = 0;
    bwr.read_consumed = 0;
    status_t err;
    do {
        ...
#if defined(__ANDROID__)
        //2.通过ioctl不停的读写操作,跟Binder Driver进行通信
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
#else
        err = INVALID_OPERATION;
#endif
        if (mProcess->mDriverFD <= 0) {
            err = -EBADF;
        }
        ...
    } while (err == -EINTR); //当被中断,则继续执行
    ...
    if (err >= NO_ERROR) {
        if (bwr.write_consumed > 0) {
            if (bwr.write_consumed < mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else {
                mOut.setDataSize(0);
                processPostWriteDerefs();
            }
        }
        if (bwr.read_consumed > 0) {
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        ...
        return NO_ERROR;
    }
    return err;
}

4.7.5 IPCThreadState::executeCommand()

  waitForResponse()收到BR_TRANSACTION响应码后,调用BHwBinder的transact()进行处理。

[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::executeCommand(int32_t cmd)
{
    ...
    switch ((uint32_t)cmd) {
    ...
    case BR_TRANSACTION:
        {
            ...
            if (tr.target.ptr) {
                // 服务管理器不会走这个分支,camera、audio服务提供者才会走这个分支
                if (reinterpret_cast(
                        tr.target.ptr)->attemptIncStrong(this)) {
                    error = reinterpret_cast(tr.cookie)->transact(tr.code, buffer,
                            &reply, tr.flags, reply_callback);
                    reinterpret_cast(tr.cookie)->decStrong(this);
                } else {
                    error = UNKNOWN_TRANSACTION;
                }

            } else {
                       //mContextObject 就是我们前面设置的 BnHwServiceManager,BnHwServiceManager没有transact,因此调用其父类BHwBinder的transact(),参考[4.7.6]
                error = mContextObject->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
            }
            ...
        }
        break;
        ...
    }
    ...
    return result;
}

4.7.6 BHwBinder::transact()

[/system/libhwbinder/Binder.cpp]
status_t BHwBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
{
    data.setDataPosition(0);

    status_t err = NO_ERROR;
    switch (code) {
        default:
                 //调用onTransact()进行code处理
            err = onTransact(code, data, reply, flags,
                    [&](auto &replyParcel) {
                        replyParcel.setDataPosition(0);
                        if (callback != nullptr) {
                            callback(replyParcel);
                        }
                    });
            break;
    }

    return err;
}

  BHwBinder->transact() 中最重要的就是onTransact(),BHwBinder本身的onTransact()没有任何实现内容, binder实体在本质上都是继承于BHwBinder的,而且我们一般都会重载onTransact()函数,所以上面这句onTransact()实际上调用的是具体binder实体的onTransact()成员函数,所以最终调用的是BnHwServiceManager::onTransact()。

  BnHwServiceManager的继承关系如下图所示:

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第7张图片

4.8 BnHwServiceManager::onTransact()

  onTransact()中,根据传入的hidl_code,调用相应的接口执行,从[4.6]可知,注册服务时,传入的hidl_code为12,因此会调用_hidl_addWithChain进行操作。

[/out/soong/.intermediates/system/libhidl/transport/manager/1.2/[email protected]_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp]
::android::status_t BnHwServiceManager::onTransact(
        uint32_t _hidl_code,
        const ::android::hardware::Parcel &_hidl_data,
        ::android::hardware::Parcel *_hidl_reply,
        uint32_t _hidl_flags,
        TransactCallback _hidl_cb) {
    ::android::status_t _hidl_err = ::android::OK;

    switch (_hidl_code) {
        case 1 /* get */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_get(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }

        case 2 /* add */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_add(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }
        ...
        case 4 /* list */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_list(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }
        ...
        case 12 /* addWithChain */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }
                  //参考[4.9]
            _hidl_err = ::android::hidl::manager::V1_2::BnHwServiceManager::_hidl_addWithChain(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }
        ...
    }
    ...
    return _hidl_err;
}

4.9 BnHwServiceManager::_hidl_addWithChain()

_hidl_addWithChain()主要步骤如下:

1.读取注册的Service Name

2. 读取注册的hidl_binder

3.通过hidl_binder,转换得到,注册时的服务实体

4.读取传入的chain数据

5.调用ServiceManager::addWithChain(),进行服务注册

6.向_hidl_reply中写入OK

7.把服务注册的结构,写入_hidl_reply

8.返回replay数据

[/out/soong/.intermediates/system/libhidl/transport/manager/1.2/[email protected]_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp]
::android::status_t BnHwServiceManager::_hidl_addWithChain(
        ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
        const ::android::hardware::Parcel &_hidl_data,
        ::android::hardware::Parcel *_hidl_reply,
        TransactCallback _hidl_cb) {
    ...

    ::android::status_t _hidl_err = ::android::OK;
    if (!_hidl_data.enforceInterface(BnHwServiceManager::Pure::descriptor)) {
        _hidl_err = ::android::BAD_TYPE;
        return _hidl_err;
    }

    const ::android::hardware::hidl_string* name;
    ::android::sp<::android::hidl::base::V1_0::IBase> service;
    const ::android::hardware::hidl_vec<::android::hardware::hidl_string>* chain;

    size_t _hidl_name_parent;

    //1.读取注册的Service Name
    _hidl_err = _hidl_data.readBuffer(sizeof(*name), &_hidl_name_parent,  reinterpret_cast(&name));

    if (_hidl_err != ::android::OK) { return _hidl_err; }

    _hidl_err = ::android::hardware::readEmbeddedFromParcel(
            const_cast<::android::hardware::hidl_string &>(*name),
            _hidl_data,
            _hidl_name_parent,
            0 /* parentOffset */);

    if (_hidl_err != ::android::OK) { return _hidl_err; }

    {
        //2. 读取注册的hidl_binder
        ::android::sp<::android::hardware::IBinder> _hidl_binder;
        _hidl_err = _hidl_data.readNullableStrongBinder(&_hidl_binder);
        if (_hidl_err != ::android::OK) { return _hidl_err; }

        //3.通过hidl_binder,转换得到,注册时的服务实体
        service = ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl_binder);
    }

    size_t _hidl_chain_parent;

    //4.读取传入的chain数据
    _hidl_err = _hidl_data.readBuffer(sizeof(*chain), &_hidl_chain_parent,  reinterpret_cast(&chain));

    if (_hidl_err != ::android::OK) { return _hidl_err; }

    size_t _hidl_chain_child;

    _hidl_err = ::android::hardware::readEmbeddedFromParcel(
            const_cast<::android::hardware::hidl_vec<::android::hardware::hidl_string> &>(*chain),
            _hidl_data,
            _hidl_chain_parent,
            0 /* parentOffset */, &_hidl_chain_child);

    if (_hidl_err != ::android::OK) { return _hidl_err; }

    for (size_t _hidl_index_0 = 0; _hidl_index_0 < chain->size(); ++_hidl_index_0) {
        _hidl_err = ::android::hardware::readEmbeddedFromParcel(
                const_cast<::android::hardware::hidl_string &>((*chain)[_hidl_index_0]),
                _hidl_data,
                _hidl_chain_child,
                _hidl_index_0 * sizeof(::android::hardware::hidl_string));

        if (_hidl_err != ::android::OK) { return _hidl_err; }

    }

    atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::addWithChain::server");
    ...
    //5.调用ServiceManager::addWithChain(),进行服务注册,参考[4.9.1]
    bool _hidl_out_success = static_cast(_hidl_this->getImpl().get())->addWithChain(*name, service, *chain);

    //6.向_hidl_reply中写入OK
    ::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);

    //7.把服务注册的结构,写入_hidl_reply
    _hidl_err = _hidl_reply->writeBool(_hidl_out_success);
    /* _hidl_err ignored! */

    atrace_end(ATRACE_TAG_HAL);
    ...
    //8.返回replay数据
    _hidl_cb(*_hidl_reply);
    return _hidl_err;
}

4.9.1 ServiceManager::addWithChain()

[/system/hwservicemanager/ServiceManager.cpp]
Return ServiceManager::addWithChain(const hidl_string& name,
                                          const sp& service,
                                          const hidl_vec& chain) {
    if (service == nullptr) {
        return false;
    }
        //1.获取 CallingContext的的sid\pid信息
    auto callingContext = getBinderCallingContext();
        //2.调用addImpl进行注册
    return addImpl(name, service, chain, callingContext);
}

4.9.2 ServiceManager::addImpl()

  获取当前binder调用的pid、sid 上下文信息后,开始注册服务,即把Demo对象注册到mServiceMap中。

  在过程中,要进行selinux检查,确认该进程有权限添加service后,再检查是否有重复注册,而且如果子类在父类上注册,则注销它,

  排除一切问题后,把需要注册的服务,注册到mServiceMap中,最后建立一个死亡连接,当服务挂掉时会接收到通知,做一些清理工作。


[/system/hwservicemanager/ServiceManager.cpp]
bool ServiceManager::addImpl(const std::string& name,
                             const sp& service,
                             const hidl_vec& interfaceChain,
                             const AccessControl::CallingContext& callingContext) {
    //传入的interfaceChain size大于0
    if (interfaceChain.size() == 0) {
        LOG(WARNING) << "Empty interface chain for " << name;
        return false;
    }

    //1.首先,检查是否有权限来否允许add()整个接口层次结构,最终调用的是selinux_check_access来检查,是否有 hwservice_manager的权限
    for(size_t i = 0; i < interfaceChain.size(); i++) {
        const std::string fqName = interfaceChain[i];

        if (!mAcl.canAdd(fqName, callingContext)) {
            return false;
        }
    }

    // 2.检查是否有重复注册
    if (interfaceChain.size() > 1) {
        // 倒数第二的条目应该是除IBase之外的最高基类。
        const std::string baseFqName = interfaceChain[interfaceChain.size() - 2];
        const HidlService *hidlService = lookup(baseFqName, name);
        if (hidlService != nullptr && hidlService->getService() != nullptr) {
            // This shouldn't occur during normal operation. Here are some cases where
            // it might get hit:
            // - bad configuration (service installed on device multiple times)
            // - race between death notification and a new service being registered
            //     (previous logs should indicate a separate problem)
            const std::string childFqName = interfaceChain[0];
            pid_t newServicePid = IPCThreadState::self()->getCallingPid();
            pid_t oldServicePid = hidlService->getDebugPid();
            LOG(WARNING) << "Detected instance of " << childFqName << " (pid: " << newServicePid
                    << ") registering over instance of or with base of " << baseFqName << " (pid: "
                    << oldServicePid << ").";
        }
    }

    // 3.如果子类在父类上注册,则注销它
    {
        // For IBar extends IFoo if IFoo/default is being registered, remove
        // IBar/default. This makes sure the following two things are equivalent
        // 1). IBar::castFrom(IFoo::getService(X))
        // 2). IBar::getService(X)
        // assuming that IBar is declared in the device manifest and there
        // is also not an IBaz extends IFoo and there is no race.
        const std::string childFqName = interfaceChain[0];
        const HidlService *hidlService = lookup(childFqName, name);
        if (hidlService != nullptr) {
            const sp remove = hidlService->getService();

            if (remove != nullptr) {
                const std::string instanceName = name;
                removeService(remove, &instanceName /* restrictToInstanceName */);
            }
        }
    }

    // 4.排除问题后,把需要注册的服务,注册到mServiceMap中
    for(size_t i = 0; i < interfaceChain.size(); i++) {
        const std::string fqName = interfaceChain[i];

        PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
        HidlService *hidlService = ifaceMap.lookup(name);
        
        if (hidlService == nullptr) {
            //服务插入 mServiceMap,以后从这取出服务,参考 [4.9.3]
            ifaceMap.insertService(
                std::make_unique(fqName, name, service, callingContext.pid));
        } else {
            hidlService->setService(service, callingContext.pid);
        }

        ifaceMap.sendPackageRegistrationNotification(fqName, name);
    }
    //建立一个死亡连接,当服务挂掉时会接收到通知,做一些清理工作
    bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
    if (!linkRet) {
        LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
    }

    return true;
}

4.9.3 ServiceManager::insertService()

  把传入的hidlservice插入到mInstanceMap 中,即 mServiceMap的value--PackageInterfaceMap 中。

[/system/hwservicemanager/ServiceManager.cpp]
void ServiceManager::PackageInterfaceMap::insertService(
        std::unique_ptr &&service) {
    mInstanceMap.insert({service->getInstanceName(), std::move(service)});
}

mServiceMap的结构如下图所示:

Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)_第8张图片

至此,我们的IDemo服务注册完成,注册步骤分为以下几个步骤:

1.服务进程先获得一个 ProcessState()的对象

2.获取HwServiceManager的代理对象HwBpServiceManager,主要通过new BpHwBinder(0)得到。

3.调用HwBpServiceManager的addWithChain,组装一个Parce数据,传入服务名称、服务实体对象--BHwBinder、执行12 /* addWithChain */

4.先通过IPCThreadThread的writeTransactionData()把上面的Parcel数据写入mOut,用来进行发送

5.通过IPCThreadThread的talkWithDriver()与HwBinder驱动通信,传递语义BINDER_WRITE_READ

6.HwServiceManager有个for循环,调用epoll_wait()监控hwbinder的变化

7.waitForResponse()收到BR_TRANSACTION响应码后,最终后调用executeCommand()进行命令执行,根据逻辑处理,最终会调用到BnHwServiceManager::onTransact(),根据传入的code=12,调用addWithChain,最终把服务名称和实体对象插入到mServiceMap这个map中

8.注册成功后,把注册结果写入reply,返回reply信息

9.最终完成服务的注册流程

 

下一节,我们一起来看看《Native层HIDL服务的获取原理

 

我的微信公众号:IngresGe

你可能感兴趣的:(Android取经之路,#,2.进程间通信,Android10.0,hwbinder,binder,hidl,native)