5.IDemo的服务获取
    IDemo的HIDL服务获取流程如下图所示:

5.1调用栈如下

5.2 main
 [\vendor\ingres\hal_demo\cpp\hal_demo_test.cpp]
 int main() {
    //1.获取IDemo这个HIDL服务的代理对象
     android::sp<IDemo> service = IDemo::getService();
  
     if(service == nullptr) {
         printf("Failed to get service\n");
         return -1;
     }
    //2.调用服务的HIDL接口 getHelloString()
     service->getHelloString("IngresGe", [&](hidl_string result) {
                 printf("%s\n", result.c_str());
         });
  
     return 0;
 }
 主要分两步:
1.获取IDemo这个HIDL服务的代理对象
2.调用服务的HIDL接口 getHelloString()
5.3 getService()
 [/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/demo/1.0/DemoAll.cpp]
 ::android::sp<IDemo> IDemo::getService(const std::string &serviceName, const bool getStub) {
     return ::android::hardware::details::getServiceInternal<BpHwDemo>(serviceName, true, getStub);
 }
 getService的调用栈如下:
根据上面的调用栈,最终进入getRawServiceInternal()
[/system/libhidl/transport/ServiceManagement.cpp]
 sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
                                                              const std::string& instance,
                                                              bool retry, bool getStub) {
     using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
     using ::android::hidl::manager::V1_0::IServiceManager;
     sp<Waiter> waiter;
  
     sp<IServiceManager1_1> sm;
     Transport transport = Transport::EMPTY;
     if (kIsRecovery) {
         transport = Transport::PASSTHROUGH;
     } else {
             //拿到HwServiceManager的对象,参考[5.4]
         sm = defaultServiceManager1_1();
         if (sm == nullptr) {
             ALOGE("getService: defaultServiceManager() is null");
             return nullptr;
         }
             //获取IDemo服务的transport,确认是直通式PASSTHROUGH,还是绑定式:HWBINDER
             //transport可以在/vendor/etc/vintf/manifest.xml中查看<transport>hwbinder</transport>
         Return<Transport> transportRet = sm->getTransport(descriptor, instance);
  
         if (!transportRet.isOk()) {
             ALOGE("getService: defaultServiceManager()->getTransport returns %s",
                   transportRet.description().c_str());
             return nullptr;
         }
         transport = transportRet;
     }
  
     const bool vintfHwbinder = (transport == Transport::HWBINDER); //绑定式服务
     const bool vintfPassthru = (transport == Transport::PASSTHROUGH); //直通式服务
         ...
  
     for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
         if (waiter == nullptr && tries > 0) {
             waiter = new Waiter(descriptor, instance, sm);
         }
         if (waiter != nullptr) {
             waiter->reset();  // don't reorder this -- see comments on reset()
         }
             //如果是绑定式的服务,调用 BpHwServiceManager::get()
         Return<sp<IBase>> ret = sm->get(descriptor, instance);
         if (!ret.isOk()) {
             ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
                   ret.description().c_str(), descriptor.c_str(), instance.c_str());
             break;
         }
         sp<IBase> base = ret;
         if (base != nullptr) {
             Return<bool> canCastRet =
                 details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
  
             if (canCastRet.isOk() && canCastRet) {
                 if (waiter != nullptr) {
                     waiter->done();
                 }
                 return base; // still needs to be wrapped by Bp class.
             }
  
             if (!handleCastError(canCastRet, descriptor, instance)) break;
         }
  
         // In case of legacy or we were not asked to retry, don't.
         if (vintfLegacy || !retry) break;
  
         if (waiter != nullptr) {
             ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
             waiter->wait(true /* timeout */);
         }
     }
  
     if (waiter != nullptr) {
         waiter->done();
     }
  
     if (getStub || vintfPassthru || vintfLegacy) {
             //如果是直通式的hidl服务,获取直通式的HwServiceManager对象来获取服务
         const sp<IServiceManager> pm = getPassthroughServiceManager();
         if (pm != nullptr) {
             sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
             if (!getStub || trebleTestingOverride) {
                 base = wrapPassthrough(base);
             }
             return base;
         }
     }
     return nullptr;
 }
getRawServiceInternal()步骤如下:
1.获取HwServiceManager的代理对象
2.获取IDemo 这个hidl服务的transport,来确认是绑定式服务,还是直通式服务
3.根据transport类型,调用不同的接口来获取服务对象 (我们设计的IDemo是绑定式hidl服务)
5.4 defaultServiceManager1_1
 [/system/libhidl/transport/ServiceManagement.cpp]
 sp<IServiceManager1_1> defaultServiceManager1_1() {
     return defaultServiceManager1_2();
 }
  
 [/system/libhidl/transport/ServiceManagement.cpp]
 defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager
 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;
 }
  
5.4.1 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() 进行处理
根据如下调用栈所示,BpHwBinder::transact()最终会转到BnHwServiceManager::_hidl_get(),实现流程和注册服务类似,相关源码分析参考上一节《Native层HIDL服务的注册原理》的[4.7.1] - [4.8]
 
 5.5 BnHwServiceManager::_hidl_get()
 [/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_get(
         ::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* fqName;
     const ::android::hardware::hidl_string* name;
  
     size_t _hidl_fqName_parent;
  
         //1.获取hidl服务的fqName
     _hidl_err = _hidl_data.readBuffer(sizeof(*fqName), &_hidl_fqName_parent,  reinterpret_cast<const void **>(&fqName));
  
     if (_hidl_err != ::android::OK) { return _hidl_err; }
  
     _hidl_err = ::android::hardware::readEmbeddedFromParcel(
             const_cast<::android::hardware::hidl_string &>(*fqName),
             _hidl_data,
             _hidl_fqName_parent,
             0 /* parentOffset */);
  
     if (_hidl_err != ::android::OK) { return _hidl_err; }
  
     size_t _hidl_name_parent;
  
         //2.获取hidl服务的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; }
  
     atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::get::server");
         ...
         //3.根据hidl服务的fqName和name,从HwServiceManager的hidl service的map中拿到服务对象
     ::android::sp<::android::hidl::base::V1_0::IBase> _hidl_out_service = static_cast<IServiceManager*>(_hidl_this->getImpl().get())->get(*fqName, *name);
  
         //4.把reply信息写入Parcel
     ::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);
  
     if (_hidl_out_service == nullptr) {
         _hidl_err = _hidl_reply->writeStrongBinder(nullptr);
     } else {
             //5.把获取的hidl服务转成IBinder对象
         ::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::getOrCreateCachedBinder(_hidl_out_service.get());
         if (_hidl_binder.get() != nullptr) {
                   //6.把转换后的IBinder对象,写入reply的Parcel数据中
             _hidl_err = _hidl_reply->writeStrongBinder(_hidl_binder);
         } else {
             _hidl_err = ::android::UNKNOWN_ERROR;
         }
     }
     /* _hidl_err ignored! */
  
     atrace_end(ATRACE_TAG_HAL);
          ..
      //7.通过回调,把reply的Parcel数据给发给client
     _hidl_cb(*_hidl_reply);
     return _hidl_err;
 }
 _hidl_get流程如下:
1.获取hidl服务的fqName
2.获取hidl服务的name
3.根据hidl服务的fqName和name,从HwServiceManager的hidl service的map中拿到服务对象
4.把reply信息写入Parcel
5.把获取的hidl服务转成IBinder对象
6.把转换后的IBinder对象,写入reply的Parcel数据中
7.通过回调,把reply的Parcel数据给发给client
5.5.1 ServiceManager::get()
 [/system/hwservicemanager/ServiceManager.cpp]
 Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
                                       const hidl_string& hidlName) {
     const std::string fqName = hidlFqName;
     const std::string name = hidlName;
  
     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
         return nullptr;
     }
  
         //1.根据fqName和name找到对应的hidlService
     HidlService* hidlService = lookup(fqName, name);
     if (hidlService == nullptr) {
         tryStartService(fqName, name);
         return nullptr;
     }
  
     //2.根据hidlService 拿到IBase的对象
     sp<IBase> service = hidlService->getService();
     if (service == nullptr) {
         tryStartService(fqName, name);
         return nullptr;
     }
  
     hidlService->guaranteeClient();
  
     hardware::addPostCommandTask([hidlService] {
         hidlService->handleClientCallbacks(false /* isCalledOnInterval */);
     });
     return service;
 }
  
5.7.3 ServiceManager::lookup()
   主要是根据fqName和name从 HwServiceManager的服务map:mServiceMap 中找到对应的hidlservice。
[/system/hwservicemanager/ServiceManager.cpp]
 HidlService* ServiceManager::lookup(const std::string& fqName, const std::string& name) {
         //1.根据fqName从 mServiceMap 中 找到一个节点
     auto ifaceIt = mServiceMap.find(fqName);
     if (ifaceIt == mServiceMap.end()) {
         return nullptr;
     }
         //2.从找到的map节点中,拿到PackageInterfaceMap的内容
     PackageInterfaceMap &ifaceMap = ifaceIt->second;
         //3.从PackageInterfaceMap中根据name找到hidlService
     HidlService *hidlService = ifaceMap.lookup(name);
     return hidlService;
 }
  
5.5.2 HidlService::getService()
 获取HidlService对象的mService

[/system/hwservicemanager/HidlService.cpp]
 sp<IBase> HidlService::getService() const {
     return mService;
 }
  
6. 协议码的转换流程
   Binder通信协议是基于Command-Reply的方式的。

7.IDemo Client\Server交互流程
   在IDemo的服务注册和获取的过程中,IDemo的服务和Client都是作为Client端,HwServiceManager作为Server端。
在IDemo的服务和client调用过程中,IDemo的服务为Server端,Client为客户端。

8.代码路径
 /system/libhwbinder/BpHwBinder.cpp
 /system/libhwbinder/IPCThreadState.cpp
 /system/libhidl/transport/ServiceManagement.cpp
 /system/libhidl/transport/include/hidl/HidlTransportSupport.h
 /vendor/ingres/hal_demo/cpp/hal_demo_test.cpp
 /out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/demo/1.0/DemoAll.cpp
 /out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp
9. 总结
   至此,Native层的HIDL服务注册和获取就梳理完了,主要就是进程和HwBinder驱动、HwServiceManager的交互流程,下一节我们再一起看看JAVA层的hidl服务注册和获取流程。









