JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的获取原理
阅读本文大约需要花费19分钟。
文章首发微信公众号:IngresGe
专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!
欢迎关注我的公众号!
[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编译系统(五)
上一节,我们学习了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通信原理(九)相关推荐
- JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的注册原理 阅读本文大约需要花费22分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的 ...
- Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
摘要:本节主要来讲解Android10.0 Native层HIDL服务的获取原理 阅读本文大约需要花费23分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...
- Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
摘要:本节主要来讲解Android10.0 Native层HIDL服务的注册原理 阅读本文大约需要花费23分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...
- HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
摘要:本节主要来讲解Android10.0 JAVA层的HIDL服务创建和JAVA层的Client验证 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...
- HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
摘要:本节主要来讲解Android10.0 Native层的HIDL服务创建和Native层的Client验证 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Androi ...
- nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)
阅读本文大约需要花费34分钟. 原创不易,如果您觉得有点用,希望可以随手转发或者点击右下角的 "在看".""分享"",拜谢! <And ...
- HwBinder原理总结-Android10.0 HwBinder通信原理(十一)
摘要:本节主要来进行Android10.0 HwBinder的原理总结 阅读本文大约需要花费14分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...
- HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
摘要:本节主要来讲解Android10.0 HwBinder驱动的流程 阅读本文大约需要花费24分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...
- HwServiceManager篇-Android10.0 HwBinder通信原理(五)
摘要:本节主要来讲解Android10.0 HwServiceManager的通信原理 阅读本文大约需要花费34分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,And ...
最新文章
- 强化学习在机器人中的应用
- java中什么是类型_什么是Java中基本数据类型?
- mysql最高安全级别双一_MySQL核心之双一原则
- 使用UTL_FILE在oracle中读写文本数据
- iphone以旧换新活动_iPhone第3轮降价背后:销售下滑库克甩锅给中国,国产手机崛起分食蛋糕...
- 静态注册BroadcastReceiver的注销问题
- Android笔记-使用okhttp3库发送http请求
- JS面向对象之封装自定义构造函数
- VMware虚拟机桥接方式与真实主机共享上网
- java nginx 重启吗_Nginx的启动、停止、平滑重启
- [linux]centos6.3安装flash插件rpm方式
- jQuery Mobile组件
- 马虎将classname加到了id属性中,造成报错
- 资源分享 | 网易云课堂价值 399 的 office 三合一自学教程
- 7z001怎么解压在安卓手机上面_手机存储告急怎么办?这份安卓清理指南请收好...
- JavaScript 剪贴板
- ip-guard如果服务器 IP 地址或机器名变更之后对客户端或控制台会有影响吗?
- 计算机配件销售系统,电脑配件销售管理系统
- 记录一次扇贝网前端实习面试
- mysql日志 事务问题_mysql因为事务日志问题无法启动