摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的获取原理

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

文章首发微信公众号: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通信原理(八)
  9. JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
  10. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
  11. HwBinder原理总结-Android10.0 HwBinder通信原理(十一)

《编译原理》

  1. 编译系统入门篇-Android10.0编译系统(一)
  2. 编译环境初始化-Android10.0编译系统(二)
  3. make编译过程-Android10.0编译系统(三)
  4. Image打包流程-Android10.0编译系统(四)
  5. Kati详解-Android10.0编译系统(五)

上一节,我们学习了JAVA层 HIDL服务的注册获取原理,这一节我们来看看JAVA层HIDL服务的获取原理。

5. 获取服务

JAVA层HIDL服务获取如下图所示:

5.1 获取服务调用栈

5.2 onClick()

[/vendor/ingres/hidl_demo/app/src/main/java/com/android/hidldemo/MainActivity.java]private IDemo mHidlService;public void onClick(View v) {switch (v.getId()) {case R.id.getHelloBtn:Log.d(TAG, "start to click");try {//1.获取IDemo的hidl服务mHidlService = IDemo.getService();if (mHidlService == null) {Log.e(TAG, "fail to get demo service");} else {Log.d(TAG, "success to get demo service");//2.调用hidl接口String result =  mHidlService.getHelloString("IngresGe");Log.d(TAG, "HIDL return:" + result);}} catch (RemoteException ex) {Log.e(TAG, "exception, fail to get demo service");}break;}}

5.3 getService()

[/frameworks/base/core/java/android/os/HwBinder.java]
public static native final IHwBinder getService(String iface,String serviceName,boolean retry)throws RemoteException, NoSuchElementException;

这是一个JNI接口,参考上一节《JAVA层HIDL服务的注册原理》中的JNI的转换,在JNI层,进入JHwBinder_native_getService()

5.4 JHwBinder_native_getService


[/frameworks/base/core/jni/android_os_HwBinder.cpp]
static jobject JHwBinder_native_getService(JNIEnv *env,jclass /* clazzObj */,jstring ifaceNameObj,jstring serviceNameObj,jboolean retry) {using ::android::hidl::base::V1_0::IBase;using ::android::hardware::details::getRawServiceInternal;std::string ifaceName;{ScopedUtfChars str(env, ifaceNameObj);if (str.c_str() == nullptr) {return nullptr;  // NPE will be pending.}ifaceName = str.c_str();}std::string serviceName;{ScopedUtfChars str(env, serviceNameObj);if (str.c_str() == nullptr) {return nullptr;  // NPE will be pending.}serviceName = str.c_str();}//1.根据servicename获取一个IBase对象,通过前文可知,这里是一个 BpHwBase对象sp<IBase> ret = getRawServiceInternal(ifaceName, serviceName, retry /* retry */, false /* getStub */);//2.将IBase对象转换为binder对象,参考[5.8]sp<hardware::IBinder> service = hardware::toBinder<hidl::base::V1_0::IBase>(ret);if (service == NULL) {signalExceptionForError(env, NAME_NOT_FOUND);return NULL;}LOG(INFO) << "HwBinder: Starting thread pool for getting: " << ifaceName << "/" << serviceName;::android::hardware::ProcessState::self()->startThreadPool();//转换hidlservice,使之成为一个Java层HwRemoteBinder对象,参考[5.9]return JHwRemoteBinder::NewObject(env, service);
}

5.5 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 {//1.拿到HwServiceManager的对象,参考[4.4.3]sm = defaultServiceManager1_1();if (sm == nullptr) {ALOGE("getService: defaultServiceManager() is null");return nullptr;}//2.获取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()}//3.如果是绑定式的服务,调用 BpHwServiceManager::get(),参考[5.6]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.6 BpHwServiceManager::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::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>> BpHwServiceManager::get(const ::android::hardware::hidl_string& fqName, const ::android::hardware::hidl_string& name){::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>>  _hidl_out = ::android::hidl::manager::V1_0::BpHwServiceManager::_hidl_get(this, this, fqName, name);return _hidl_out;
}

_hidl_get流程如下:

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

2.组装Parcel数据

3.写入RPC头信息"android.hidl.manager@1.2::IServiceManager"

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

5.调用remote的transact,发送 1 /* get */的命令获取hidl服务

7.得到返回的reply数据

8.从reply中读取hidl binder的信息,转换成hidl service,发送出去


::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>> BpHwServiceManager::_hidl_get(::android::hardware::IInterface *_hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_string& fqName, const ::android::hardware::hidl_string& name) {...::android::hardware::Parcel _hidl_data; //定义一个Parcel的data数据包::android::hardware::Parcel _hidl_reply;//定义一个Parcel的reply数据包::android::status_t _hidl_err;::android::hardware::Status _hidl_status;::android::sp<::android::hidl::base::V1_0::IBase> _hidl_out_service;//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_fqName_parent;//2.写入fqName,如果没有配置的话,name为"default"_hidl_err = _hidl_data.writeBuffer(&fqName, sizeof(fqName), &_hidl_fqName_parent);if (_hidl_err != ::android::OK) { goto _hidl_error; }_hidl_err = ::android::hardware::writeEmbeddedToParcel(fqName,&_hidl_data,_hidl_fqName_parent,0 /* parentOffset */);if (_hidl_err != ::android::OK) { goto _hidl_error; }size_t _hidl_name_parent;//3.写入hidl 服务name_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; }//5.调用BpHwBinder::transact()//_hidl_this 指的是 BpHwServiceManager,通过asBinder转换为传输层面的BpHwBinder对象,其实就是取出BpHwServiceManager的成员变量mRemote的值_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(1 /* get */, _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; }{//7.从reply的数据中读取,hidl_Binder::android::sp<::android::hardware::IBinder> _hidl_binder;_hidl_err = _hidl_reply.readNullableStrongBinder(&_hidl_binder);if (_hidl_err != ::android::OK) { goto _hidl_error; }//8.把hidl binder转换成hidl service_hidl_out_service = ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl_binder);}..._hidl_status.setFromStatusT(_hidl_err);//9.返回hidl service对象return ::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>>(_hidl_out_service);_hidl_error:_hidl_status.setFromStatusT(_hidl_err);return ::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>>(_hidl_status);
}

根据如下调用栈所示,BpHwBinder::transact()最终会转到BnHwServiceManager::_hidl_get()

5.7 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.7.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找到对应的hidlServiceHidlService* 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.2 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找到hidlServiceHidlService *hidlService = ifaceMap.lookup(name);return hidlService;
}

5.7.3 HidlService::getService()

返回hidlservice的mService成员

[/system/hwservicemanager/HidlService.cpp]
sp<IBase> HidlService::getService() const {return mService;
}

HwServiceManager中hidl服务的管理map:

5.8 toBinder()

toBinder接口将IBase对象转换为binder对象,其实就是从BpHwBase中拿到其成员变量mRemote中的BpHwBinder对象

[/system/libhidl/transport/include/hidl/HidlBinderSupport.h]
sp<IBinder> toBinder(sp<IType> iface) {IType *ifacePtr = iface.get();return getOrCreateCachedBinder(ifacePtr);
}sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr) {if (ifacePtr == nullptr) {return nullptr;}if (ifacePtr->isRemote()) {using ::android::hidl::base::V1_0::BpHwBase;//从BpHwBase中拿到其成员变量mRemote中的BpHwBinder对象BpHwBase* bpBase = static_cast<BpHwBase*>(ifacePtr);BpHwRefBase* bpRefBase = static_cast<BpHwRefBase*>(bpBase);return sp<IBinder>(bpRefBase->remote());}std::string descriptor = details::getDescriptor(ifacePtr);if (descriptor.empty()) {// interfaceDescriptor failsreturn nullptr;}// for get + setstd::unique_lock<std::mutex> _lock = details::gBnMap->lock();wp<BHwBinder> wBnObj = details::gBnMap->getLocked(ifacePtr, nullptr);sp<IBinder> sBnObj = wBnObj.promote();if (sBnObj == nullptr) {auto func = details::getBnConstructorMap().get(descriptor, nullptr);if (!func) {// TODO(b/69122224): remove this static variable when prebuilts updatedfunc = details::gBnConstructorMap->get(descriptor, nullptr);}LOG_ALWAYS_FATAL_IF(func == nullptr, "%s gBnConstructorMap returned null for %s", __func__,descriptor.c_str());sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr)));LOG_ALWAYS_FATAL_IF(sBnObj == nullptr, "%s Bn constructor function returned null for %s",__func__, descriptor.c_str());details::gBnMap->setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get()));}return sBnObj;
}

5.9 JHwRemoteBinder::NewObject()

在JNI层将调用JHwRemoteBinder::NewObject()函数来创建一个Java层HwRemoteBinder对象,转换hidlservice,使之成为一个Java层HwRemoteBinder对象

[/frameworks/base/core/jni/android_os_HwRemoteBinder.cpp]
jobject JHwRemoteBinder::NewObject(JNIEnv *env, const sp<hardware::IBinder> &binder) {ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));// XXX Have to look up the constructor here because otherwise that static// class initializer isn't called and gProxyOffsets.constructID is undefined :(jmethodID constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "()V");jobject obj = env->NewObject(clazz.get(), constructID);JHwRemoteBinder::GetNativeContext(env, obj)->setBinder(binder);return obj;
}

5.10 asInterface(android.os.IHwBinder binder)

通过服务查询得到HwRemoteBinder对象,这个只是传输层面的对象而已,需要转换为业务层面的对象,这个是由IXXX.asInterface函数完成

[out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo-V1.0-java_gen_java/gen/srcs/vendor/ingres/demo/V1_0/IDemo.java]/* package private */ static IDemo asInterface(android.os.IHwBinder binder) {if (binder == null) {return null;}android.os.IHwInterface iface =binder.queryLocalInterface(kInterfaceName);if ((iface != null) && (iface instanceof IDemo)) {return (IDemo)iface;}IDemo proxy = new IDemo.Proxy(binder);try {for (String descriptor : proxy.interfaceChain()) {if (descriptor.equals(kInterfaceName)) {return proxy;}}} catch (android.os.RemoteException e) {}return null;}

6. Client-Server接口调用

JAVA层 Client和Server的对象转换如下图所示:

在[4] 和[5]节中,我们知道了服务注册registerService()和获取服务getService()的流程,接下来我们再看一看接口调用是如何进行的。

上面调用的流程,其实和registerService()、getService()类似,都是组装Parcel数据,准备服务端的code,调用HwBinderProxy.transact()发送到服务端。

但是和服务注册不同的是,在服务注册中,Native的HwServiceManager是Server端,服务实体是Client端。接口调用时,服务实体是Server端。

服务端接收到CLient的请求后,根据下图的流程,最终流转到服务实体的onTransact()中,对解析出来的Parcel数据进行处理。

7.代码路径

/system/libhwbinder/BpHwBinder.cpp
/system/libhwbinder/IPCThreadState.cpp
/system/hwservicemanager/HidlService.cpp
/system/hwservicemanager/ServiceManager.cpp
/system/libhidl/transport/ServiceManagement.cpp
/system/libhidl/transport/include/hidl/HidlBinderSupport.h
/frameworks/base/core/jni/android_os_HwBinder.cpp
/frameworks/base/core/java/android/os/HwBinder.java
/frameworks/base/core/jni/android_os_HwRemoteBinder.cpp
/vendor/ingres/hal_demo/java/src/com/android/demo/Server.java
/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo-V1.0-java_gen_java/gen/srcs/vendor/ingres/demo/V1_0/IDemo.java
/out/soong/.intermediates/system/libhidl/transport/base/1.0/android.hidl.base@1.0_genc++/gen/android/hidl/base/1.0/BaseAll.cpp
/out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp

我的微信公众号:IngresGe

JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)相关推荐

  1. JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)

    摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的注册原理 阅读本文大约需要花费22分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的 ...

  2. Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)

    摘要:本节主要来讲解Android10.0 Native层HIDL服务的获取原理 阅读本文大约需要花费23分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...

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

    摘要:本节主要来讲解Android10.0 Native层HIDL服务的注册原理 阅读本文大约需要花费23分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...

  4. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)

    摘要:本节主要来讲解Android10.0 JAVA层的HIDL服务创建和JAVA层的Client验证 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

  5. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)

    摘要:本节主要来讲解Android10.0 Native层的HIDL服务创建和Native层的Client验证 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Androi ...

  6. nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)

    阅读本文大约需要花费34分钟. 原创不易,如果您觉得有点用,希望可以随手转发或者点击右下角的 "在看".""分享"",拜谢! <And ...

  7. HwBinder原理总结-Android10.0 HwBinder通信原理(十一)

    摘要:本节主要来进行Android10.0 HwBinder的原理总结 阅读本文大约需要花费14分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...

  8. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)

    摘要:本节主要来讲解Android10.0 HwBinder驱动的流程 阅读本文大约需要花费24分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...

  9. HwServiceManager篇-Android10.0 HwBinder通信原理(五)

    摘要:本节主要来讲解Android10.0 HwServiceManager的通信原理 阅读本文大约需要花费34分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,And ...

最新文章

  1. 强化学习在机器人中的应用
  2. java中什么是类型_什么是Java中基本数据类型?
  3. mysql最高安全级别双一_MySQL核心之双一原则
  4. 使用UTL_FILE在oracle中读写文本数据
  5. iphone以旧换新活动_iPhone第3轮降价背后:销售下滑库克甩锅给中国,国产手机崛起分食蛋糕...
  6. 静态注册BroadcastReceiver的注销问题
  7. Android笔记-使用okhttp3库发送http请求
  8. JS面向对象之封装自定义构造函数
  9. VMware虚拟机桥接方式与真实主机共享上网
  10. java nginx 重启吗_Nginx的启动、停止、平滑重启
  11. [linux]centos6.3安装flash插件rpm方式
  12. jQuery Mobile组件
  13. 马虎将classname加到了id属性中,造成报错
  14. 资源分享 | 网易云课堂价值 399 的 office 三合一自学教程
  15. 7z001怎么解压在安卓手机上面_手机存储告急怎么办?这份安卓清理指南请收好...
  16. JavaScript 剪贴板
  17. ip-guard如果服务器 IP 地址或机器名变更之后对客户端或控制台会有影响吗?
  18. 计算机配件销售系统,电脑配件销售管理系统
  19. 记录一次扇贝网前端实习面试
  20. mysql日志 事务问题_mysql因为事务日志问题无法启动

热门文章

  1. linux 程序输出 logo,Linux下制作logo并显示到开发板上
  2. php请求接口数据,php curl请求接口并获取数据的示例代码
  3. 我来悟微服务(3)-需求管理
  4. CentOS上如何把Web服务器从Apache换到nginx
  5. 直线职权::参谋职权::职能职权
  6. GNS3与SecureCRT关联问题
  7. ruby应用:puppet
  8. 组播技术中IP地址到MAC地址的映射
  9. 7个极具杀伤性的Linux命令
  10. httpHandlers使用和问题