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::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 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 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 service = new BnHwServiceManager(manager);
IPCThreadState::self()->setTheContextObject(service);
// Then tell binder kernel
ioctl(binder_fd, BINDER_SET_CONTEXT_MGR, 0);
[email protected]_genc++\gen\android\hidl\manager\1.0\ServiceManagerAll.cpp
BnHwServiceManager::BnHwServiceManager(const ::android::sp &_hidl_impl)
        : ::android::hidl::base::V1_0::BnHwBase(_hidl_impl, "[email protected]", "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。

AndroidO Treble架构下hwservicemanager启动过程_第1张图片

system\libhidl\transport\ServiceManagement.cpp

sp 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(
                        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( ProcessState::self()->getContextObject(NULL))来获取hwservicemanager的代理。

system\libhwbinder\ProcessState.cpp

sp ProcessState::getContextObject(const sp& /*caller*/)
{
    return getStrongProxyForHandle(0);
}
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp 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< IServiceManager, BpHwServiceManager, BnHwServiceManager>进行转换。

system\libhidl\transport\include\hidl\HidlBinderSupport.h

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;
    }
    if (binderIface->localBinder() == nullptr) {
        return new BpHwServiceManager(binderIface);
    }
    sp base = static_cast(binderIface.get())->getImpl();
    if (details::canCastInterface(base.get(), IServiceManager::descriptor)) {
        BnHwServiceManager* stub = static_cast(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(binderIface.get())
然后通过BnHwBase的getImpl()函数得到其业务实现对象IBase。
sp base =static_cast(binderIface.get())->getImpl();
然后检查业务接口是否相同:
if (details::canCastInterface(base.get(),IType::descriptor))
如果业务接口类型相同,那么再次将这个本地binder对象转换为孙类BnHwServiceManager类型:
BnHwServiceManager* stub = static_cast(binderIface.get());
然后返回业务实现类对象ServiceManager对象。
[email protected]_genc++\gen\android\hidl\manager\1.0\ServiceManagerAll.cpp
BpHwServiceManager::BpHwServiceManager(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)
        : BpInterface(_hidl_impl),
          ::android::hardware::details::HidlInstrumentor("[email protected]", "IServiceManager") {
}
AndroidO Treble架构下hwservicemanager启动过程_第2张图片
system\libhwbinder\include\hwbinder\IInterface.h
template
class BpInterface : public INTERFACE, public IInterface, public BpHwRefBase
{
public:
                                BpInterface(const sp& remote);
    virtual IBinder*            onAsBinder();
};
所以在构造BpHwServiceManager对象时,首先会调用BpInterface的构造函数:
template
inline BpInterface::BpInterface(const sp& remote)
    : BpHwRefBase(remote)
{
}
这里又会将参数传递给BpInterface的父类BpHwRefBase,并调用其构造函数:
system\libhwbinder\Binder.cpp
BpHwRefBase::BpHwRefBase(const sp& 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的值,转换过程如下:

AndroidO Treble架构下hwservicemanager启动过程_第3张图片

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

AndroidO Treble架构下hwservicemanager启动过程_第4张图片

你可能感兴趣的:(【Android,系统分析】)