2026/5/14 5:58:10
网站建设
项目流程
加强网站硬件建设方案,免费的制作网站,网络信息公司名字,沈阳建设工程项目管理中心目录一、整体框架二、HAL 层服务端实现三、Framework 层客户端实现Binderized HALs 实例分析
一、整体框架
对于 Binderized HALs#xff0c;HAL 层以进程的形式存在#xff0c;内部有一个 HwBinder 服务端对象#xff0c;对外提供 HwBinder 远程调用服务。Framework 通…目录一、整体框架二、HAL 层服务端实现三、Framework 层客户端实现Binderized HALs 实例分析一、整体框架对于Binderized HALsHAL 层以进程的形式存在内部有一个HwBinder服务端对象对外提供HwBinder远程调用服务。Framework 通过HwBinder远程调用到 HAL 中的函数这些函数直接访问具体的驱动。在源码下device/google/coral/vibrator/目录下是 Google 为 pixel4、pixel4 xl 实现的振动器 HAL其类型就是 Binderized HALs。本文分析其具体实现二、HAL 层服务端实现HAL 层表现为一个进程进程对应的代码位于device/google/coral/vibrator整体结构如下我们从 Android.bp 下手cc_defaults{name:android.hardware.vibrator1.3-defaults.coral,defaults:[hidl_defaults],relative_install_path:hw,shared_libs:[libhidlbase,libcutils,libhidltransport,liblog,libhwbinder,libutils,libhardware,android.hardware.vibrator1.0,android.hardware.vibrator1.1,android.hardware.vibrator1.2,android.hardware.vibrator1.3,],}cc_defaults{name:PtsVibratorHalFloralDefaults,defaults:[android.hardware.vibrator1.3-defaults.coral],static_libs:[android.hardware.vibrator1.3-impl.coral],test_suites:[general-tests,pts,],multilib:{lib32:{suffix:32,},lib64:{suffix:64,},},}cc_library{name:android.hardware.vibrator1.3-impl.coral,defaults:[android.hardware.vibrator1.3-defaults.coral],srcs:[Hardware.cpp,Vibrator.cpp,],export_include_dirs:[.],vendor_available:true,}cc_binary{name:android.hardware.vibrator1.3-service.coral,defaults:[android.hardware.vibrator1.3-defaults.coral],init_rc:[android.hardware.vibrator1.3-service.coral.rc],vintf_fragments:[android.hardware.vibrator1.3-service.coral.xml],srcs:[service.cpp],static_libs:[android.hardware.vibrator1.3-impl.coral],proprietary:true,}一个共享库android.hardware.vibrator1.3-impl.coral一个 native 可执行程序android.hardware.vibrator1.3-service.coral。android.hardware.vibrator1.3-impl.coral共享库中 :Hardware.cpp 中对振动器驱动的访问包装成了两个对象HwApi HwCal。Vibrator.cpp 链接了android.hardware.vibrator1.3库内部有一个 Vibrator类继承自android.hardware.vibrator1.3库中 IVibratorIVibrator 是由hardware/interfaces/vibrator/1.3/IVibrator.hal编译出来的。Vibrator 类是一个HwBinder服务端类对外提供了调用振动器的接口内部实现是通过调用HwApi HwCal对象的成员函数实现的。android.hardware.vibrator1.3-service.coral可执行程序status_tregisterVibratorService(){spVibratorvibratornewVibrator(std::make_uniqueHwApi(),std::make_uniqueHwCal());returnvibrator-registerAsService();}intmain(){configureRpcThreadpool(1,true);status_tstatusregisterVibratorService();if(status!OK){returnstatus;}joinRpcThreadpool();}实现上很简单向 HwServiceManager 注册 Vibrator配置 HwBinder 线程具体振动器的操作细节就不看了这不是我们的重点。三、Framework 层客户端实现对于客户端我们只要知道 Hal 对外提供的接口即可这个接口由hardware/interfaces/vibrator/1.3/IVibrator.hal描述package android.hardware.vibrator1.3;import 1.0::EffectStrength;import 1.0::Status;import 1.2::IVibrator;interface IVibrator extends 1.2::IVibrator{supportsExternalControl()generates(bool supports);setExternalControl(bool enabled)generates(Status status);perform_1_3(Effect effect,EffectStrength strength)generates(Status status,uint32_tlengthMs);};frameworks/base/services/core/java/com/android/server/VibratorService.java本身是一个 Binder 服务端向 App 提供服务同时也是一个HwBinder客户端通过 JNI 访问到 HAL 服务端。publicclassVibratorServiceextendsIVibratorService.StubimplementsInputManager.InputDeviceListener{// ......staticnativebooleanvibratorExists();staticnativevoidvibratorInit();staticnativevoidvibratorOn(longmilliseconds);staticnativevoidvibratorOff();staticnativebooleanvibratorSupportsAmplitudeControl();staticnativevoidvibratorSetAmplitude(intamplitude);staticnativelongvibratorPerformEffect(longeffect,longstrength);staticnativebooleanvibratorSupportsExternalControl();staticnativevoidvibratorSetExternalControl(booleanenabled);// ......}VibratorService 中有多个 native 方法这些方法用于远程调用 Hal 层。对应的 JNI 函数实现在frameworks/base/services/core/jni/com_android_server_VibratorService.cpp#defineLOG_TAGVibratorService#includeandroid/hardware/vibrator/1.0/IVibrator.h#includeandroid/hardware/vibrator/1.0/types.h#includeandroid/hardware/vibrator/1.0/IVibrator.h#includeandroid/hardware/vibrator/1.1/types.h#includeandroid/hardware/vibrator/1.2/IVibrator.h#includeandroid/hardware/vibrator/1.2/types.h#includeandroid/hardware/vibrator/1.3/IVibrator.h#includejni.h#includenativehelper/JNIHelp.h#includeandroid_runtime/AndroidRuntime.h#includeutils/misc.h#includeutils/Log.h#includehardware/vibrator.h#includeinttypes.h#includestdio.husing android::hardware::Return;using android::hardware::vibrator::V1_0::EffectStrength;using android::hardware::vibrator::V1_0::Status;using android::hardware::vibrator::V1_1::Effect_1_1;namespace V1_0android::hardware::vibrator::V1_0;namespace V1_1android::hardware::vibrator::V1_1;namespace V1_2android::hardware::vibrator::V1_2;namespace V1_3android::hardware::vibrator::V1_3;namespace android{staticconstexprintNUM_TRIES2;// Creates a ReturnR with STATUS::EX_NULL_POINTER.templateclass RinlineReturnRNullptrStatus(){using::android::hardware::Status;returnReturnR{Status::fromExceptionCode(Status::EX_NULL_POINTER)};}// Helper used to transparently deal with the vibrator HAL becoming unavailable.templateclass R,class I,class...Args0,class...Args1ReturnRhalCall(ReturnR(I::*fn)(Args0...),Args1...args1){// Assume that if getService returns a nullptr, HAL is not available on the// device.staticspIsHalI::getService();staticbool sAvailablesHal!nullptr;if(!sAvailable){returnNullptrStatusR();}// ReturnR doesnt have a default constructor, so make a ReturnR with// STATUS::EX_NONE.using::android::hardware::Status;ReturnRret{Status::fromExceptionCode(Status::EX_NONE)};// Note that ret is guaranteed to be changed after this loop.for(inti0;iNUM_TRIES;i){ret(sHalnullptr)?NullptrStatusR():(*sHal.*fn)(std::forwardArgs1(args1)...);if(ret.isOk()){break;}ALOGE(Failed to issue command to vibrator HAL. Retrying.);// Restoring connection to the HAL.sHalI::tryGetService();}returnret;}templateclass RboolisValidEffect(jlong effect){if(effect0){returnfalse;}R valstatic_castR(effect);autoiterhardware::hidl_enum_rangeR();returnval*iter.begin()val*std::prev(iter.end());}staticvoidvibratorInit(JNIEnv/* env */,jobject/* clazz */){halCall(V1_0::IVibrator::ping).isOk();}staticjbooleanvibratorExists(JNIEnv*/* env */,jobject/* clazz */){returnhalCall(V1_0::IVibrator::ping).isOk()?JNI_TRUE:JNI_FALSE;}staticvoidvibratorOn(JNIEnv*/* env */,jobject/* clazz */,jlong timeout_ms){Status retStatushalCall(V1_0::IVibrator::on,timeout_ms).withDefault(Status::UNKNOWN_ERROR);if(retStatus!Status::OK){ALOGE(vibratorOn command failed (%PRIu32).,static_castuint32_t(retStatus));}}staticvoidvibratorOff(JNIEnv*/* env */,jobject/* clazz */){Status retStatushalCall(V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR);if(retStatus!Status::OK){ALOGE(vibratorOff command failed (%PRIu32).,static_castuint32_t(retStatus));}}staticjlongvibratorSupportsAmplitudeControl(JNIEnv*,jobject){returnhalCall(V1_0::IVibrator::supportsAmplitudeControl).withDefault(false);}staticvoidvibratorSetAmplitude(JNIEnv*,jobject,jint amplitude){Status statushalCall(V1_0::IVibrator::setAmplitude,static_castuint32_t(amplitude)).withDefault(Status::UNKNOWN_ERROR);if(status!Status::OK){ALOGE(Failed to set vibrator amplitude (%PRIu32).,static_castuint32_t(status));}}staticjbooleanvibratorSupportsExternalControl(JNIEnv*,jobject){returnhalCall(V1_3::IVibrator::supportsExternalControl).withDefault(false);}staticvoidvibratorSetExternalControl(JNIEnv*,jobject,jboolean enabled){Status statushalCall(V1_3::IVibrator::setExternalControl,static_castuint32_t(enabled)).withDefault(Status::UNKNOWN_ERROR);if(status!Status::OK){ALOGE(Failed to set vibrator external control (%PRIu32).,static_castuint32_t(status));}}staticjlongvibratorPerformEffect(JNIEnv*,jobject,jlong effect,jint strength){Status status;uint32_tlengthMs;autocallback[status,lengthMs](Status retStatus,uint32_tretLengthMs){statusretStatus;lengthMsretLengthMs;};EffectStrengtheffectStrength(static_castEffectStrength(strength));Returnvoidret;if(isValidEffectV1_0::Effect(effect)){rethalCall(V1_0::IVibrator::perform,static_castV1_0::Effect(effect),effectStrength,callback);}elseif(isValidEffectEffect_1_1(effect)){rethalCall(V1_1::IVibrator::perform_1_1,static_castEffect_1_1(effect),effectStrength,callback);}elseif(isValidEffectV1_2::Effect(effect)){rethalCall(V1_2::IVibrator::perform_1_2,static_castV1_2::Effect(effect),effectStrength,callback);}elseif(isValidEffectV1_3::Effect(effect)){rethalCall(V1_3::IVibrator::perform_1_3,static_castV1_3::Effect(effect),effectStrength,callback);}else{ALOGW(Unable to perform haptic effect, invalid effect ID (%PRId32),static_castint32_t(effect));return-1;}if(!ret.isOk()){ALOGW(Failed to perform effect (%PRId32),static_castint32_t(effect));return-1;}if(statusStatus::OK){returnlengthMs;}elseif(status!Status::UNSUPPORTED_OPERATION){// Dont warn on UNSUPPORTED_OPERATION, thats a normal event and just means the motor// doesnt have a pre-defined waveform to perform for it, so we should just give the// opportunity to fall back to the framework waveforms.ALOGE(Failed to perform haptic effect: effect%PRId64, strength%PRId32, error%PRIu32).,static_castint64_t(effect),static_castint32_t(strength),static_castuint32_t(status));}return-1;}staticconstJNINativeMethod method_table[]{{vibratorExists,()Z,(void*)vibratorExists},{vibratorInit,()V,(void*)vibratorInit},{vibratorOn,(J)V,(void*)vibratorOn},{vibratorOff,()V,(void*)vibratorOff},{vibratorSupportsAmplitudeControl,()Z,(void*)vibratorSupportsAmplitudeControl},{vibratorSetAmplitude,(I)V,(void*)vibratorSetAmplitude},{vibratorPerformEffect,(JJ)J,(void*)vibratorPerformEffect},{vibratorSupportsExternalControl,()Z,(void*)vibratorSupportsExternalControl},{vibratorSetExternalControl,(Z)V,(void*)vibratorSetExternalControl},};intregister_android_server_VibratorService(JNIEnv*env){returnjniRegisterNativeMethods(env,com/android/server/VibratorService,method_table,NELEM(method_table));}};所有的函数都通过halcall来实现halcall中会去从 HwServiceManager 中去获取Vibrator Hal的代理对象然后通过这个代理对象发起远程调用从而调用到 HAL 层。最后我们再来看 HAL 端的 VINTF 配置文件/Project/android-10.0.0_r41/device/google/coral/vibrator/android.hardware.vibrator1.3-service.coral.xmlmanifest version1.0typedevicehal formathidlnameandroid.hardware.vibrator/nametransporthwbinder/transportversion1.3/versioninterfacenameIVibrator/nameinstancedefault/instance/interface/hal/manifest注意这里 transport 指定了 hal 的类型为 hwbinder也就是我们说的Binderized hal。