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

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

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

《系统启动篇》

Android系统架构
Android是怎么启动的
Android 10.0系统启动之init进程
Android10.0系统启动之Zygote进程
Android 10.0 系统启动之SystemServer进程
Android 10.0 系统服务之ActivityMnagerService
Android10.0系统启动之Launcher(桌面)启动流程
Android10.0应用进程创建过程以及Zygote的fork流程
Android 10.0 PackageManagerService(一)工作原理及启动流程
Android 10.0 PackageManagerService(二)权限扫描
Android 10.0 PackageManagerService(三)APK扫描
Android 10.0 PackageManagerService(四)APK安装流程
《日志系统篇》

Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​
《Binder通信原理》:

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

《HwBinder通信原理》

HwBinder入门篇-Android10.0 HwBinder通信原理(一)
 HIDL详解-Android10.0 HwBinder通信原理(二)
HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
HwServiceManager篇-Android10.0 HwBinder通信原理(五)
Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
HwBinder原理总结-Android10.0 HwBinder通信原理(十一)
《编译原理》

编译系统入门篇-Android10.0编译系统(一)
编译环境初始化-Android10.0编译系统(二)
make编译过程-Android10.0编译系统(三)
Image打包流程-Android10.0编译系统(四
Kati详解-Android10.0编译系统(五)
Blueprint简介-Android10.0编译系统(六)
Blueprint代码详细分析-Android10.0编译系统(七)
Android.bp 语法浅析-Android10.0编译系统(八)
Ninja简介-Android10.0编译系统(九)
Ninja提升编译速度的方法-Android10.0编译系统(十)
Android10.0编译系统(十一)

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

 mServiceMap对应的key为package interface 名称,例如"android.hidl.manager@1.0::IServiceManager", 对应的value为一个PackageInterfaceMap结构体,其中包含了lookup()、insertService()等方法,

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

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

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

 

2. Native层的HwBinder架构

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驱动进行数据交互。

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

     

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

 

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

4.1 调用栈如下

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\vendor.ingres.demo@1.0_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<IBase>& service, const std::string& name) {
    if (service == nullptr) {
        return UNEXPECTED_NULL;
    }
    
    //1.获取HwServiceManager代理对象:BpHwServiceManager,fromBinder最终为 new BpHwServiceManager(new BpHwBinder(0))
    //参考[4.5]
    sp<IServiceManager1_2> sm = defaultServiceManager1_2();
    if (sm == nullptr) {
        return INVALID_OPERATION;
    }
 
    bool registered = false;
    Return<void> 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<IServiceManager1_2> defaultServiceManager1_2()
  defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager
 

[/system/libhidl/transport/ServiceManagement.cpp]
sp<IServiceManager1_2> defaultServiceManager1_2() {
    using android::hidl::manager::V1_2::BnHwServiceManager;
    using android::hidl::manager::V1_2::BpHwServiceManager;
 
    static std::mutex gDefaultServiceManagerLock;
    static sp<IServiceManager1_2> gDefaultServiceManager;
 
    {
        std::lock_guard<std::mutex> _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<IServiceManager1_2, BpHwServiceManager, BnHwServiceManager>(
                    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<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);  //传入handle = 0, HwServiceManager的handle就为0
}

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

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> 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 <typename IType, typename ProxyType, typename StubType>
sp<IType> fromBinder(const sp<IBinder>& 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<IBase> base = static_cast<BnHwBase*>(binderIface.get())->getImpl();
    if (details::canCastInterface(base.get(), IType::descriptor)) {
        StubType* stub = static_cast<StubType*>(binderIface.get());
        return stub->getImpl();
    } else {
        return nullptr;
    }
}

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

 

 

4.6 BpHwServiceManager::addWithChain()

[\out\soong\.intermediates\system\libhidl\transport\manager\1.2\android.hidl.manager@1.2_genc++\gen\android\hidl\manager\1.2\ServiceManagerAll.cpp]
::android::hardware::Return<bool> 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<bool>  _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头信息"android.hidl.manager@1.2::IServiceManager"

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

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

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

7.得到返回的reply数据
 

::android::hardware::Return<bool> 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<void *> _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头信息"android.hidl.manager@1.2::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<void *> _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<bool>(_hidl_out_success);
 
_hidl_error:
    _hidl_status.setFromStatusT(_hidl_err);
    return ::android::hardware::Return<bool>(_hidl_status);
}

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

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<uintptr_t>(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<RefBase::weakref_type*>(
                        tr.target.ptr)->attemptIncStrong(this)) {
                    error = reinterpret_cast<BHwBinder*>(tr.cookie)->transact(tr.code, buffer,
                            &reply, tr.flags, reply_callback);
                    reinterpret_cast<BHwBinder*>(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的继承关系如下图所示:

 

4.8 BnHwServiceManager::onTransact()

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

[/out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_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/android.hidl.manager@1.2_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<const void **>(&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<const void **>(&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<IServiceManager*>(_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<bool> ServiceManager::addWithChain(const hidl_string& name,
                                          const sp<IBase>& service,
                                          const hidl_vec<hidl_string>& 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<IBase>& service,
                             const hidl_vec<hidl_string>& 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<IBase> 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<HidlService>(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<HidlService> &&service) {
    mInstanceMap.insert({service->getInstanceName(), std::move(service)});
}

mServiceMap的结构如下图所示:

至此,我们的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.最终完成服务的注册流程
 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值