AndroidO Treble架构下hwservicemanager启动过程

hwservicemanager是hidl服务管理中心,负责管理系统中的所有hidl服务,由init进程启动。

service hwservicemanager /system/bin/hwservicemanager  
    user system  
    disabled  
    group system readproc  
    critical  
    onrestart setprop hwservicemanager.ready false  
    onrestart class_restart hal  
    onrestart class_restart early_hal  
    writepid /dev/cpuset/system-background/tasks  
    class animation  
    shutdown critical  

hwservicemanager的源码位于:system/hwservicemanager

C:\Source\androido\system\hwservicemanager\service.cpp

int main() {  
    configureRpcThreadpool(1, true /* callerWillJoin */);  
    //创建ServiceManager对象  
    ServiceManager *manager = new ServiceManager();  
    //将ServiceManager对象自身注册到mServiceMap表中  
    if (!manager->add(serviceName, manager)) {  
        ALOGE("Failed to register hwservicemanager with itself.");  
    }  
    //创建TokenManager对象  
    TokenManager *tokenManager = new TokenManager();  
    //将TokenManager对象自身注册到mServiceMap表中  
    if (!manager->add(serviceName, tokenManager)) {  
        ALOGE("Failed to register ITokenManager with hwservicemanager.");  
    }  
    //建立消息循环  
    sp<Looper> looper(Looper::prepare(0 /* opts */));  

    int binder_fd = -1;  
    //将主线程加入binder线程池,并得到/dev/hwbinder句柄  
    IPCThreadState::self()->setupPolling(&binder_fd);  
    if (binder_fd < 0) {  
        ALOGE("Failed to aquire binder FD. Aborting...");  
        return -1;  
    }  
    // Flush after setupPolling(), to make sure the binder driver  
    // knows about this thread handling commands.  
    IPCThreadState::self()->flushCommands();  
    //主线程监听EVENT_INPUT,通过回调BinderCallback处理  
    sp<BinderCallback> cb(new BinderCallback);  
    if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,  
            nullptr) != 1) {  
        ALOGE("Failed to add hwbinder FD to Looper. Aborting...");  
        return -1;  
    }  
    //创建BnHwServiceManager对象  
    // Tell IPCThreadState we're the service manager  
    sp<BnHwServiceManager> service = new BnHwServiceManager(manager);  
    IPCThreadState::self()->setTheContextObject(service);  
    // Then tell binder kernel  
    ioctl(binder_fd, BINDER_SET_CONTEXT_MGR, 0);  
    // Only enable FIFO inheritance for hwbinder  
    // FIXME: remove define when in the kernel  
#define BINDER_SET_INHERIT_FIFO_PRIO    _IO('b', 10)  

    int rc = ioctl(binder_fd, BINDER_SET_INHERIT_FIFO_PRIO);  
    if (rc) {  
        ALOGE("BINDER_SET_INHERIT_FIFO_PRIO failed with error %d\n", rc);  
    }  
    //通过属性方式告知其他进程,hwservicemanager已经就绪  
    rc = property_set("hwservicemanager.ready", "true");  
    if (rc) {  
        ALOGE("Failed to set \"hwservicemanager.ready\" (error %d). "\  
              "HAL services will not start!\n", rc);  
    }  
    //进入消息循环  
    while (true) {  
        looper->pollAll(-1 /* timeoutMillis */);  
    }  

    return 0;  
}  

hwservicemanager启动过程比较简单,最重要的就是以下三行:

sp<BnHwServiceManager> service = new BnHwServiceManager(manager);  
IPCThreadState::self()->setTheContextObject(service);  
// Then tell binder kernel  
ioctl(binder_fd, BINDER_SET_CONTEXT_MGR, 0);  

android.hidl.manager@1.0_genc++\gen\android\hidl\manager\1.0\ServiceManagerAll.cpp

BnHwServiceManager::BnHwServiceManager(const ::android::sp<IServiceManager> &_hidl_impl)  
        : ::android::hidl::base::V1_0::BnHwBase(_hidl_impl, "android.hidl.manager@1.0", "IServiceManager") {   
            _hidl_mImpl = _hidl_impl;  
            auto prio = ::android::hardware::details::gServicePrioMap.get(_hidl_impl, {SCHED_NORMAL, 0});  
            mSchedPolicy = prio.sched_policy;  
            mSchedPriority = prio.prio;  
}  

这里创建一个binder本地对象BnHwServiceManager,然后注册到binder驱动中,让其他client进程都可以找到这个binder本地对象,然后为其创建binder代理对象。需要注意的是BnHwServiceManager的成员变量_hidl_mImpl保存的是ServiceManager实例,ServiceManager类实现了IServiceManager接口。

hwservicemanager代理获取过程

在前面的文章中介绍了Hal进程的启动过程及hidl服务的注册过程,在hidl服务注册时,首先要获取hwservicemanager的binder代理对象,然后将hidl服务传递给他的本地binder对象,在hwservicemanager启动时,创建好了binder本地对象BnHwServiceManager并注册给了binder驱动,这样Client进程就可以通过handle为0创建binder代理对象,从而通过binder驱动可以找到BnHwServiceManager。

这里写图片描述

system\libhidl\transport\ServiceManagement.cpp

sp<IServiceManager> defaultServiceManager() {  
    {  
        AutoMutex _l(details::gDefaultServiceManagerLock);  
        if (details::gDefaultServiceManager != NULL) {  
            return details::gDefaultServiceManager;  
        }  

        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;  
        }  

        waitForHwServiceManager();  

        while (details::gDefaultServiceManager == NULL) {  
            details::gDefaultServiceManager =  
                    fromBinder<IServiceManager, BpHwServiceManager, BnHwServiceManager>(  
                        ProcessState::self()->getContextObject(NULL));  
            if (details::gDefaultServiceManager == NULL) {  
                LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";  
                sleep(1);  
            }  
        }  
    }  

    return details::gDefaultServiceManager;  
} 

void waitForHwServiceManager() {  
    using std::literals::chrono_literals::operator""s;  

    while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) {  
        LOG(WARNING) << "Waited for hwservicemanager.ready for a second, waiting another...";  
    }  
}  

首先根据属性”hwservicemanager.ready”值判断hwservicemanager进程是否启动就绪,如果hwservicemanager已经启动,那么通过fromBinder

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

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)  
{  
    sp<IBinder> result;  

    AutoMutex _l(mLock);  

    handle_entry* e = lookupHandleLocked(handle);  

    if (e != NULL) {  
        // We need to create a new BpHwBinder if there isn't currently one, OR we  
        // are unable to acquire a weak reference on this current one.  See comment  
        // in getWeakProxyForHandle() for more info about this.  
        IBinder* b = e->binder;  
        if (b == NULL || !e->refs->attemptIncWeak(this)) {  
            b = new BpHwBinder(handle);  
            e->binder = b;  
            if (b) e->refs = b->getWeakRefs();  
            result = b;  
        } else {  
            // This little bit of nastyness is to allow us to add a primary  
            // reference to the remote proxy when this team doesn't have one  
            // but another team is sending the handle to us.  
            result.force_set(b);  
            e->refs->decWeak(this);  
        }  
    }  

    return result;  
} 

因此通过ProcessState::self()->getContextObject(NULL)将得到一个BpHwBinder对象,然后通过fromBinder

sp<IServiceManager> 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;  
    }  
    if (binderIface->localBinder() == nullptr) {  
        return new BpHwServiceManager(binderIface);  
    }  
    sp<IBase> base = static_cast<BnHwBase*>(binderIface.get())->getImpl();  
    if (details::canCastInterface(base.get(), IServiceManager::descriptor)) {  
        BnHwServiceManager* stub = static_cast<BnHwServiceManager*>(binderIface.get());  
        return stub->getImpl();  
    } else {  
        return nullptr;  
    }  
}  

这里将创建一个BpHwServiceManager对象,ProcessState::self()->getContextObject(NULL)如果返回的是远程binder对象,那么基于BpHwBinder创建BpHwServiceManager对象,BpHwBinder负责数据传输,而BpHwServiceManager服务数据业务,业务数据在BpHwServiceManager层打包好后,转交给BpHwBinder发送。如果getContextObject(NULL)返回的是本地binder对象,那么将这个本地binder对象强制转换为BnHwBase类型,从上图可知BnHwBase继承BHwBinder类,BHwBinder即是本地binder对象。

static_cast<BnHwBase*>(binderIface.get())

然后通过BnHwBase的getImpl()函数得到其业务实现对象IBase。

sp<IBase> base =static_cast<BnHwBase*>(binderIface.get())->getImpl();

然后检查业务接口是否相同:

if (details::canCastInterface(base.get(),IType::descriptor))

如果业务接口类型相同,那么再次将这个本地binder对象转换为孙类BnHwServiceManager类型:

BnHwServiceManager* stub = static_cast<BnHwServiceManager*>(binderIface.get());

然后返回业务实现类对象ServiceManager对象。 
android.hidl.manager@1.0_genc++\gen\android\hidl\manager\1.0\ServiceManagerAll.cpp

BpHwServiceManager::BpHwServiceManager(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)  
        : BpInterface<IServiceManager>(_hidl_impl),  
          ::android::hardware::details::HidlInstrumentor("android.hidl.manager@1.0", "IServiceManager") {  
}  

这里写图片描述

system\libhwbinder\include\hwbinder\IInterface.h

template<typename INTERFACE>  
class BpInterface : public INTERFACE, public IInterface, public BpHwRefBase  
{  
public:  
                                BpInterface(const sp<IBinder>& remote);  
    virtual IBinder*            onAsBinder();  
};  

所以在构造BpHwServiceManager对象时,首先会调用BpInterface的构造函数:

template<typename INTERFACE>  
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)  
    : BpHwRefBase(remote)  
{  
} 

这里又会将参数传递给BpInterface的父类BpHwRefBase,并调用其构造函数: 
system\libhwbinder\Binder.cpp

BpHwRefBase::BpHwRefBase(const sp<IBinder>& o)  
    : mRemote(o.get()), mRefs(NULL), mState(0)  
{  
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);  

    if (mRemote) {  
        mRemote->incStrong(this);           // Removed on first IncStrong().  
        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.  
    }  
} 

到此就是BpHwServiceManager对象的完整构造过程,BpHwServiceManager的成员变量mRemote保存的是BpHwBinder binder代理对象。BpHwServiceManager是业务层面的代理对象,而BpHwBinder是传输层面的代理对象。在通过BpHwServiceManager::_hidl_add 注册hidl服务时,会执行以下binder传输:

_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(2 /* add */, _hidl_data, &_hidl_reply);

这里的_hidl_this指向的是BpHwServiceManager,通过asBinder转换为传输层面的BpHwBinder对象,其实就是取出BpHwServiceManager的成员变量mRemote的值,转换过程如下:

这里写图片描述

hwservicemanager进程中的servicemanager作为hidl服务,同样适用了hwbinder框架,其类继承关系图如下: 
这里写图片描述

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值