前面介绍了HIDL服务在native层的实现过程,包括HIDL服务加载创建、服务注册、服务查询过程等,那么Java层是否也实现了相关的服务框架呢? 通常情况下,所有的Hal都实现在native层面,每个hal进程都是一个native进程,由init进程启动,在hal进程启动时会完成HIDL服务注册,Framework Server进程不一定完全是native进程,比如system_server进程,它运行在虚拟机环境中,由zygote进程fork而来,这时,Java层也需要请求HIDL服务,因此Android不仅在native层HIDL化了hal,在Java层同样也定义了相关的服务框架。
上图是Java层binder和hwbinder之间的类基础图对比。当我们定义一个.hal接口文件时,通过hidl-gen编译为Java文件后,将按上图中的类继承关系自动生成代码。
如上图所示,当我们定义IXXX.hal文件后,通过编译将在out/target/common/gen/JAVA_LIBRARIES目录下生成对应的IXXX.java,该文件按上述类继承关系自动生成相关代码,我们只需要定义一个XXXImp类,继承Stub并实现所有方法,然后在某个服务进程中创建一个XXXImp对象,并调用registerService()函数进行hidl服务注册,如下所示:
- XXXImp mXXXImp = new XXXImp();
- mXXXImp.registerAsService(”XXXImp”);
XXXImp mXXXImp = new XXXImp(); mXXXImp.registerAsService("XXXImp");
这样就完成了一个Java层的hidl服务注册,当然在当前Android系统中,大部分还是native层的hidl服务,Java层的hidl服务还是比较少的。从上述可知,Java层的hidl服务包括2个步骤:
1. hidl服务对象创建;
2.hidl服务注册;
Java hidl服务创建过程
从上面的类继承图可知,hidl服务实现类继承于Stub,Stub又继承于HwBinder,因此创建一个XXXImp对象时,会调用HwBinder的构造函数。
frameworks\base\core\java\android\os\HwBinder.java
- public HwBinder() {
- native_setup();
- sNativeRegistry.registerNativeAllocation(
- this,
- mNativeContext);
- }
public HwBinder() { native_setup(); sNativeRegistry.registerNativeAllocation( this, mNativeContext); }
- static {
- long freeFunction = native_init();
- sNativeRegistry = new NativeAllocationRegistry(
- HwBinder.class.getClassLoader(),
- freeFunction,
- 128 /* size */);
- }
static { long freeFunction = native_init(); sNativeRegistry = new NativeAllocationRegistry( HwBinder.class.getClassLoader(), freeFunction, 128 /* size */); }创建HwBinder对象会首先执行native_init()函数,然后调用native_setup()函数。
frameworks\base\core\jni\android_os_HwBinder.cpp
- static jlong JHwBinder_native_init(JNIEnv *env) {
- JHwBinder::InitClass(env);
- return reinterpret_cast<jlong>(&releaseNativeContext);
- }
- static void JHwBinder_native_setup(JNIEnv *env, jobject thiz) {
- sp<JHwBinderHolder> context = new JHwBinderHolder;
- JHwBinder::SetNativeContext(env, thiz, context);
- }
static jlong JHwBinder_native_init(JNIEnv *env) { JHwBinder::InitClass(env); return reinterpret_cast<jlong>(&releaseNativeContext); } static void JHwBinder_native_setup(JNIEnv *env, jobject thiz) { sp<JHwBinderHolder> context = new JHwBinderHolder; JHwBinder::SetNativeContext(env, thiz, context); }
这里创建一个JHwBinderHolder 对象,并保存在HwBinder类的mNativeContext变量中。
- sp<JHwBinderHolder> JHwBinder::SetNativeContext(
- JNIEnv *env, jobject thiz, const sp<JHwBinderHolder> &context) {
- sp<JHwBinderHolder> old =
- (JHwBinderHolder *)env->GetLongField(thiz, gFields.contextID);
- if (context != NULL) {
- context->incStrong(NULL /* id */);
- }
- if (old != NULL) {
- old->decStrong(NULL /* id */);
- }
- env->SetLongField(thiz, gFields.contextID, (long)context.get());
- return old;
- }
sp<JHwBinderHolder> JHwBinder::SetNativeContext( JNIEnv *env, jobject thiz, const sp<JHwBinderHolder> &context) { sp<JHwBinderHolder> old = (JHwBinderHolder *)env->GetLongField(thiz, gFields.contextID); if (context != NULL) { context->incStrong(NULL /* id */); } if (old != NULL) { old->decStrong(NULL /* id */); } env->SetLongField(thiz, gFields.contextID, (long)context.get()); return old; }
这里出现了多个binder类型:HwBinder、JHwBinderHolder、JHwBinder他们的类继承图如下:
红线标识了这3个类对象之间的关系,为了更加清晰地描述他们之间的关联关系,如下图所示:
Java hidl服务注册过程
当我们创建好了hidl服务类对象后,将调用mXXXImp.registerAsService(“XXXImp”);进行注册,注册过程如下:
frameworks\base\core\java\android\os\HwBinder.java
- public native final void registerService(String serviceName)
- throws RemoteException;
public native final void registerService(String serviceName) throws RemoteException;
frameworks\base\core\jni\android_os_HwBinder.cpp
- static void JHwBinder_native_registerService(
- JNIEnv *env,
- jobject thiz,
- jstring serviceNameObj) {
- if (serviceNameObj == NULL) {
- jniThrowException(env, ”java/lang/NullPointerException”, NULL);
- return;
- }
- const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL);
- if (serviceName == NULL) {
- return; // XXX exception already pending?
- }
- sp<hardware::IBinder> binder = JHwBinder::GetNativeBinder(env, thiz);
- /* TODO(b/33440494) this is not right */
- sp<hidl::base::V1_0::IBase> base = new hidl::base::V1_0::BpHwBase(binder);
- auto manager = hardware::defaultServiceManager();
- if (manager == nullptr) {
- LOG(ERROR) << ”Could not get hwservicemanager.”;
- signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
- return;
- }
- Return<bool> ret = manager->add(serviceName, base);
- env->ReleaseStringUTFChars(serviceNameObj, serviceName);
- serviceName = NULL;
- bool ok = ret.isOk() && ret;
- if (ok) {
- LOG(INFO) << ”Starting thread pool.”;
- ::android::hardware::ProcessState::self()->startThreadPool();
- }
- signalExceptionForError(env, (ok ? OK : UNKNOWN_ERROR), true /* canThrowRemoteException */);
- }
static void JHwBinder_native_registerService( JNIEnv *env, jobject thiz, jstring serviceNameObj) { if (serviceNameObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return; } const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL); if (serviceName == NULL) { return; // XXX exception already pending? } sp<hardware::IBinder> binder = JHwBinder::GetNativeBinder(env, thiz); /* TODO(b/33440494) this is not right */ sp<hidl::base::V1_0::IBase> base = new hidl::base::V1_0::BpHwBase(binder); auto manager = hardware::defaultServiceManager(); if (manager == nullptr) { LOG(ERROR) << "Could not get hwservicemanager."; signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */); return; } Return<bool> ret = manager->add(serviceName, base); env->ReleaseStringUTFChars(serviceNameObj, serviceName); serviceName = NULL; bool ok = ret.isOk() && ret; if (ok) { LOG(INFO) << "Starting thread pool."; ::android::hardware::ProcessState::self()->startThreadPool(); } signalExceptionForError(env, (ok ? OK : UNKNOWN_ERROR), true /* canThrowRemoteException */); }
首先通过GetNativeBinder函数得到JHwBinder对象,然后创建一个BpHwBase来包装JHwBinder,并将BpHwBase注册到hwservicemanager中。
- sp<JHwBinder> JHwBinder::GetNativeBinder(
- JNIEnv *env, jobject thiz) {
- JHwBinderHolder *holder =
- reinterpret_cast<JHwBinderHolder *>(
- env->GetLongField(thiz, gFields.contextID));
- return holder->get(env, thiz);
- }
sp<JHwBinder> JHwBinder::GetNativeBinder( JNIEnv *env, jobject thiz) { JHwBinderHolder *holder = reinterpret_cast<JHwBinderHolder *>( env->GetLongField(thiz, gFields.contextID)); return holder->get(env, thiz); }
- sp<JHwBinder> get(JNIEnv *env, jobject obj) {
- Mutex::Autolock autoLock(mLock);
- sp<JHwBinder> binder = mBinder.promote();
- if (binder == NULL) {
- binder = new JHwBinder(env, obj);
- mBinder = binder;
- }
- return binder;
- }
sp<JHwBinder> get(JNIEnv *env, jobject obj) { Mutex::Autolock autoLock(mLock); sp<JHwBinder> binder = mBinder.promote(); if (binder == NULL) { binder = new JHwBinder(env, obj); mBinder = binder; } return binder; }
从HwBinder的成员变量mNativeContext中得到JHwBinderHolder的对象指针,然后调用其get函数得到JHwBinder对象。然后将JHwBinder封装为BpHwBase对象。
[email protected]_genc++\gen\android\hidl\base\1.0\BaseAll.cpp
- BpHwBase::BpHwBase(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)
- : BpInterface<IBase>(_hidl_impl),
- ::android::hardware::details::HidlInstrumentor(”[email protected]”, “IBase”) {
- }
BpHwBase::BpHwBase(const ::android::sp<::android::hardware::IBinder> &_hidl_impl) : BpInterface<IBase>(_hidl_impl), ::android::hardware::details::HidlInstrumentor("[email protected]", "IBase") { }
因此Java hidl服务向hwservicemanager注册的还是BpHwBase对象,BpHwBase的mRemote变量引用的是JHwBinder对象,JHwBinder的成员变量mObject又保存了Java层的HwBinder的引用。
从进程空间角度来看Java hidl服务注册,如下:
BpHwBase注册到hwservicemanager的详细过程在前面的文章中已经有详细的介绍,这里不再重复。
Java hidl服务查询过程
既然有注册,那么肯定存在服务查询,那么Client进程如何查询这些运行在Server进程端的Java hidl服务呢?
out/target/common/gen/JAVA_LIBRARIES/android.hardware.wifi-V1.1-java_intermediates/android/hardware/wifi/V1_1/IWifi.java
- public static IWifi getService(String serviceName) throws android.os.RemoteException {
- return IWifi.asInterface(android.os.HwBinder.getService(“[email protected]::IWifi”,serviceName));
- }
- public static IWifi getService() throws android.os.RemoteException {
- return IWifi.asInterface(android.os.HwBinder.getService(“[email protected]::IWifi”,“default”));
- }
public static IWifi getService(String serviceName) throws android.os.RemoteException { return IWifi.asInterface(android.os.HwBinder.getService("[email protected]::IWifi",serviceName)); } public static IWifi getService() throws android.os.RemoteException { return IWifi.asInterface(android.os.HwBinder.getService("[email protected]::IWifi","default")); }
这里首先调用android.os.HwBinder.getService(“[email protected]::IWifi”,”default”)来查询hidl服务,然后通过asInterface接口转换为与业务相关的接口对象。
服务查询过程
这里首先通过HwBinder.getService()接口从hwservicemanager进程中根据包名”[email protected]::IWifi”,”default”的hwBinder代理。
frameworks\base\core\java\android\os\HwBinder.java
- public static native final IHwBinder getService(
- String iface,
- String serviceName)
- throws RemoteException, NoSuchElementException;
public static native final IHwBinder getService( String iface, String serviceName) throws RemoteException, NoSuchElementException;
frameworks\base\core\jni\android_os_HwBinder.cpp
- static jobject JHwBinder_native_getService(
- JNIEnv *env,
- jclass /* clazzObj */,
- jstring ifaceNameObj,
- jstring serviceNameObj) {
- using ::android::hidl::base::V1_0::IBase;
- using ::android::hidl::manager::V1_0::IServiceManager;
- if (ifaceNameObj == NULL) {
- jniThrowException(env, ”java/lang/NullPointerException”, NULL);
- return NULL;
- }
- if (serviceNameObj == NULL) {
- jniThrowException(env, ”java/lang/NullPointerException”, NULL);
- return NULL;
- }
- auto manager = hardware::defaultServiceManager();
- if (manager == nullptr) {
- LOG(ERROR) << ”Could not get hwservicemanager.”;
- signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
- return NULL;
- }
- const char *ifaceNameCStr = env->GetStringUTFChars(ifaceNameObj, NULL);
- if (ifaceNameCStr == NULL) {
- return NULL; // XXX exception already pending?
- }
- std::string ifaceName(ifaceNameCStr);
- env->ReleaseStringUTFChars(ifaceNameObj, ifaceNameCStr);
- ::android::hardware::hidl_string ifaceNameHStr;
- ifaceNameHStr.setToExternal(ifaceName.c_str(), ifaceName.size());
- const char *serviceNameCStr = env->GetStringUTFChars(serviceNameObj, NULL);
- if (serviceNameCStr == NULL) {
- return NULL; // XXX exception already pending?
- }
- std::string serviceName(serviceNameCStr);
- env->ReleaseStringUTFChars(serviceNameObj, serviceNameCStr);
- ::android::hardware::hidl_string serviceNameHStr;
- serviceNameHStr.setToExternal(serviceName.c_str(), serviceName.size());
- LOG(INFO) << ”Looking for service ”
- << ifaceName
- << ”/”
- << serviceName;
- Return<IServiceManager::Transport> transportRet =
- manager->getTransport(ifaceNameHStr, serviceNameHStr);
- if (!transportRet.isOk()) {
- signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
- return NULL;
- }
- IServiceManager::Transport transport = transportRet;
- #ifdef __ANDROID_TREBLE__
- #ifdef __ANDROID_DEBUGGABLE__
- const char* testingOverride = std::getenv(“TREBLE_TESTING_OVERRIDE”);
- const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY)
- && testingOverride && !strcmp(testingOverride, ”true”);
- #else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__
- const bool vintfLegacy = false;
- #endif // __ANDROID_DEBUGGABLE__
- #else // not __ANDROID_TREBLE__
- const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY);
- #endif // __ANDROID_TREBLE__”;
- if (transport != IServiceManager::Transport::HWBINDER && !vintfLegacy) {
- LOG(ERROR) << ”service ” << ifaceName << “ declares transport method ”
- << toString(transport) << ” but framework expects hwbinder.”;
- signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
- return NULL;
- }
- Return<sp<hidl::base::V1_0::IBase>> ret = manager->get(ifaceNameHStr, serviceNameHStr);
- if (!ret.isOk()) {
- signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
- return NULL;
- }
- sp<hardware::IBinder> service = hardware::toBinder<
- hidl::base::V1_0::IBase, hidl::base::V1_0::BpHwBase>(ret);
- if (service == NULL) {
- signalExceptionForError(env, NAME_NOT_FOUND);
- return NULL;
- }
- LOG(INFO) << ”Starting thread pool.”;
- ::android::hardware::ProcessState::self()->startThreadPool();
- return JHwRemoteBinder::NewObject(env, service);
- }
static jobject JHwBinder_native_getService( JNIEnv *env, jclass /* clazzObj */, jstring ifaceNameObj, jstring serviceNameObj) { using ::android::hidl::base::V1_0::IBase; using ::android::hidl::manager::V1_0::IServiceManager; if (ifaceNameObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return NULL; } if (serviceNameObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return NULL; } auto manager = hardware::defaultServiceManager(); if (manager == nullptr) { LOG(ERROR) << "Could not get hwservicemanager."; signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */); return NULL; } const char *ifaceNameCStr = env->GetStringUTFChars(ifaceNameObj, NULL); if (ifaceNameCStr == NULL) { return NULL; // XXX exception already pending? } std::string ifaceName(ifaceNameCStr); env->ReleaseStringUTFChars(ifaceNameObj, ifaceNameCStr); ::android::hardware::hidl_string ifaceNameHStr; ifaceNameHStr.setToExternal(ifaceName.c_str(), ifaceName.size()); const char *serviceNameCStr = env->GetStringUTFChars(serviceNameObj, NULL); if (serviceNameCStr == NULL) { return NULL; // XXX exception already pending? } std::string serviceName(serviceNameCStr); env->ReleaseStringUTFChars(serviceNameObj, serviceNameCStr); ::android::hardware::hidl_string serviceNameHStr; serviceNameHStr.setToExternal(serviceName.c_str(), serviceName.size()); LOG(INFO) << "Looking for service " << ifaceName << "/" << serviceName; Return<IServiceManager::Transport> transportRet = manager->getTransport(ifaceNameHStr, serviceNameHStr); if (!transportRet.isOk()) { signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */); return NULL; } IServiceManager::Transport transport = transportRet;