前面介绍了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层同样也定义了相关的服务框架。

hoover架构详细介绍 hil架构_hoover架构详细介绍

上图是Java层binder和hwbinder之间的类基础图对比。当我们定义一个.hal接口文件时,通过hidl-gen编译为Java文件后,将按上图中的类继承关系自动生成代码。

hoover架构详细介绍 hil架构_java_02

如上图所示,当我们定义IXXX.hal文件后,通过编译将在out/target/common/gen/JAVA_LIBRARIES目录下生成对应的IXXX.java,该文件按上述类继承关系自动生成相关代码,我们只需要定义一个XXXImp类,继承Stub并实现所有方法,然后在某个服务进程中创建一个XXXImp对象,并调用registerService()函数进行hidl服务注册,如下所示:

1. XXXImp mXXXImp = new XXXImp();  
2. 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的构造函数。

hoover架构详细介绍 hil架构_Java_03

frameworks\base\core\java\android\os\HwBinder.java


1. public HwBinder() {  
2.     native_setup();  
3.   
4.     sNativeRegistry.registerNativeAllocation(  
5.             this,  
6.             mNativeContext);  
7. }
1. static {  
2.     long freeFunction = native_init();  
3.   
4.     sNativeRegistry = new NativeAllocationRegistry(  
5.             HwBinder.class.getClassLoader(),  
6.             freeFunction,  
7.             128 /* size */);  
8. }

创建HwBinder对象会首先执行native_init()函数,然后调用native_setup()函数。

frameworks\base\core\jni\android_os_HwBinder.cpp

1. static jlong JHwBinder_native_init(JNIEnv *env) {  
2.     JHwBinder::InitClass(env);  
3.   
4.     return reinterpret_cast<jlong>(&releaseNativeContext);  
5. }  
6.   
7. static void JHwBinder_native_setup(JNIEnv *env, jobject thiz) {  
8.     sp<JHwBinderHolder> context = new JHwBinderHolder;  
9.     JHwBinder::SetNativeContext(env, thiz, context);  
10. }

这里创建一个JHwBinderHolder 对象,并保存在HwBinder类的mNativeContext变量中。

1. sp<JHwBinderHolder> JHwBinder::SetNativeContext(  
2.         JNIEnv *env, jobject thiz, const sp<JHwBinderHolder> &context) {  
3.     sp<JHwBinderHolder> old =  
4.         (JHwBinderHolder *)env->GetLongField(thiz, gFields.contextID);  
5.   
6.     if (context != NULL) {  
7.         context->incStrong(NULL /* id */);  
8.     }  
9.   
10.     if (old != NULL) {  
11.         old->decStrong(NULL /* id */);  
12.     }  
13.   
14.     env->SetLongField(thiz, gFields.contextID, (long)context.get());  
15.   
16.     return old;  
17. }

这里出现了多个binder类型:HwBinder、JHwBinderHolder、JHwBinder他们的类继承图如下:

hoover架构详细介绍 hil架构_java_04

红线标识了这3个类对象之间的关系,为了更加清晰地描述他们之间的关联关系,如下图所示:

hoover架构详细介绍 hil架构_java_05

 

Java hidl服务注册过程

当我们创建好了hidl服务类对象后,将调用mXXXImp.registerAsService(“XXXImp”);进行注册,注册过程如下:

frameworks\base\core\java\android\os\HwBinder.java

1. public native final void registerService(String serviceName)  
2.         throws RemoteException;

frameworks\base\core\jni\android_os_HwBinder.cpp

1. static void JHwBinder_native_registerService(  
2.         JNIEnv *env,  
3.         jobject thiz,  
4.         jstring serviceNameObj) {  
5.     if (serviceNameObj == NULL) {  
6.         jniThrowException(env, ”java/lang/NullPointerException”, NULL);  
7.         return;  
8.     }  
9.   
10.     const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL);  
11.     if (serviceName == NULL) {  
12.         return;  // XXX exception already pending?  
13.     }  
14.   
15.     sp<hardware::IBinder> binder = JHwBinder::GetNativeBinder(env, thiz);  
16.   
17.     /* TODO(b/33440494) this is not right */  
18.     sp<hidl::base::V1_0::IBase> base = new hidl::base::V1_0::BpHwBase(binder);  
19.   
20.     auto manager = hardware::defaultServiceManager();  
21.   
22.     if (manager == nullptr) {  
23.         LOG(ERROR) << ”Could not get hwservicemanager.”;  
24.         signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);  
25.         return;  
26.     }  
27.   
28.     Return<bool> ret = manager->add(serviceName, base);  
29.   
30.     env->ReleaseStringUTFChars(serviceNameObj, serviceName);  
31.     serviceName = NULL;  
32.   
33.     bool ok = ret.isOk() && ret;  
34.   
35.     if (ok) {  
36.         LOG(INFO) << ”Starting thread pool.”;  
37.         ::android::hardware::ProcessState::self()->startThreadPool();  
38.     }  
39.   
40.     signalExceptionForError(env, (ok ? OK : UNKNOWN_ERROR), true /* canThrowRemoteException */);  
41. }

首先通过GetNativeBinder函数得到JHwBinder对象,然后创建一个BpHwBase来包装JHwBinder,并将BpHwBase注册到hwservicemanager中。

1. sp<JHwBinder> JHwBinder::GetNativeBinder(  
2.         JNIEnv *env, jobject thiz) {  
3.     JHwBinderHolder *holder =  
4.         reinterpret_cast<JHwBinderHolder *>(  
5.                 env->GetLongField(thiz, gFields.contextID));  
6.   
7.     return holder->get(env, thiz);  
8. }
1. sp<JHwBinder> get(JNIEnv *env, jobject obj) {  
2.     Mutex::Autolock autoLock(mLock);  
3.   
4.     sp<JHwBinder> binder = mBinder.promote();  
5.   
6.     if (binder == NULL) {  
7.         binder = new JHwBinder(env, obj);  
8.         mBinder = binder;  
9.     }  
10.   
11.     return binder;  
12. }

从HwBinder的成员变量mNativeContext中得到JHwBinderHolder的对象指针,然后调用其get函数得到JHwBinder对象。然后将JHwBinder封装为BpHwBase对象。

android.hidl.base@1.0_genc++\gen\android\hidl\base\1.0\BaseAll.cpp

1. BpHwBase::BpHwBase(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)  
2.         : BpInterface<IBase>(_hidl_impl),  
3.           ::android::hardware::details::HidlInstrumentor(”android.hidl.base@1.0”, “IBase”) {  
4. }

因此Java hidl服务向hwservicemanager注册的还是BpHwBase对象,BpHwBase的mRemote变量引用的是JHwBinder对象,JHwBinder的成员变量mObject又保存了Java层的HwBinder的引用。

hoover架构详细介绍 hil架构_java_06

从进程空间角度来看Java hidl服务注册,如下:

hoover架构详细介绍 hil架构_android_07

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
1. public static IWifi getService(String serviceName) throws android.os.RemoteException {  
2.     return IWifi.asInterface(android.os.HwBinder.getService(“android.hardware.wifi@1.1::IWifi”,serviceName));  
3. }  
4. 5. public static IWifi getService() throws android.os.RemoteException {  
6.     return IWifi.asInterface(android.os.HwBinder.getService(“android.hardware.wifi@1.1::IWifi”,“default”));  
7. }

这里首先调用android.os.HwBinder.getService(“android.hardware.wifi@1.1::IWifi”,”default”)来查询hidl服务,然后通过asInterface接口转换为与业务相关的接口对象。

服务查询过程

这里首先通过HwBinder.getService()接口从hwservicemanager进程中根据包名”android.hardware.wifi@1.1::IWifi”,”default”的hwBinder代理。

frameworks\base\core\java\android\os\HwBinder.java

    1. public static native final IHwBinder getService(  
    2.         String iface,  
    3.         String serviceName)  
    4.     throws RemoteException, NoSuchElementException;

    frameworks\base\core\jni\android_os_HwBinder.cpp

    1. static jobject JHwBinder_native_getService(  
    2.         JNIEnv *env,  
    3.         jclass /* clazzObj */,  
    4.         jstring ifaceNameObj,  
    5.         jstring serviceNameObj) {  
    6.   
    7.     using ::android::hidl::base::V1_0::IBase;  
    8.     using ::android::hidl::manager::V1_0::IServiceManager;  
    9.   
    10.     if (ifaceNameObj == NULL) {  
    11.         jniThrowException(env, ”java/lang/NullPointerException”, NULL);  
    12.         return NULL;  
    13.     }  
    14.     if (serviceNameObj == NULL) {  
    15.         jniThrowException(env, ”java/lang/NullPointerException”, NULL);  
    16.         return NULL;  
    17.     }  
    18.   
    19.     auto manager = hardware::defaultServiceManager();  
    20.   
    21.     if (manager == nullptr) {  
    22.         LOG(ERROR) << ”Could not get hwservicemanager.”;  
    23.         signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);  
    24.         return NULL;  
    25.     }  
    26.   
    27.     const char *ifaceNameCStr = env->GetStringUTFChars(ifaceNameObj, NULL);  
    28.     if (ifaceNameCStr == NULL) {  
    29.         return NULL; // XXX exception already pending?  
    30.     }  
    31.     std::string ifaceName(ifaceNameCStr);  
    32.     env->ReleaseStringUTFChars(ifaceNameObj, ifaceNameCStr);  
    33.     ::android::hardware::hidl_string ifaceNameHStr;  
    34.     ifaceNameHStr.setToExternal(ifaceName.c_str(), ifaceName.size());  
    35.   
    36.     const char *serviceNameCStr = env->GetStringUTFChars(serviceNameObj, NULL);  
    37.     if (serviceNameCStr == NULL) {  
    38.         return NULL; // XXX exception already pending?  
    39.     }  
    40.     std::string serviceName(serviceNameCStr);  
    41.     env->ReleaseStringUTFChars(serviceNameObj, serviceNameCStr);  
    42.     ::android::hardware::hidl_string serviceNameHStr;  
    43.     serviceNameHStr.setToExternal(serviceName.c_str(), serviceName.size());  
    44.   
    45.     LOG(INFO) << ”Looking for service ”  
    46.               << ifaceName  
    47.               << ”/”  
    48.               << serviceName;  
    49.   
    50.     Return<IServiceManager::Transport> transportRet =  
    51.             manager->getTransport(ifaceNameHStr, serviceNameHStr);  
    52.   
    53.     if (!transportRet.isOk()) {  
    54.         signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);  
    55.         return NULL;  
    56.     }  
    57.   
    58.     IServiceManager::Transport transport = transportRet;  
    59.   
    60. #ifdef __ANDROID_TREBLE__  
    61. #ifdef __ANDROID_DEBUGGABLE__  
    62.     const char* testingOverride = std::getenv(“TREBLE_TESTING_OVERRIDE”);  
    63.     const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY)  
    64.             && testingOverride && !strcmp(testingOverride, ”true”);  
    65. #else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__  
    66.     const bool vintfLegacy = false;  
    67. #endif // __ANDROID_DEBUGGABLE__  
    68. #else // not __ANDROID_TREBLE__  
    69.     const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY);  
    70. #endif // __ANDROID_TREBLE__”;  
    71.   
    72.     if (transport != IServiceManager::Transport::HWBINDER && !vintfLegacy) {  
    73.         LOG(ERROR) << ”service ” << ifaceName << “ declares transport method ”  
    74.                    << toString(transport) << ” but framework expects hwbinder.”;  
    75.         signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);  
    76.         return NULL;  
    77.     }  
    78.   
    79.     Return<sp<hidl::base::V1_0::IBase>> ret = manager->get(ifaceNameHStr, serviceNameHStr);  
    80.   
    81.     if (!ret.isOk()) {  
    82.         signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);  
    83.         return NULL;  
    84.     }  
    85.   
    86.     sp<hardware::IBinder> service = hardware::toBinder<  
    87.             hidl::base::V1_0::IBase, hidl::base::V1_0::BpHwBase>(ret);  
    88.   
    89.     if (service == NULL) {  
    90.         signalExceptionForError(env, NAME_NOT_FOUND);  
    91.         return NULL;  
    92.     }  
    93.   
    94.     LOG(INFO) << ”Starting thread pool.”;  
    95.     ::android::hardware::ProcessState::self()->startThreadPool();  
    96.   
    97.     return JHwRemoteBinder::NewObject(env, service);  
    98. }


    首先检查当前查询的hidl服务的Transport是否为hwbinder,然后通过hardware::defaultServiceManager()得到IServiceManager 在native层的业务代理对象BpHwServiceManager,接着通过BpHwServiceManager向hwservicemanager查询hidl服务,其实就是根据接口包名从hwservicemanager进程中的mServiceMap表中查找对应的HidlService对象,从而得到BpHwBase对象,通过前面文章对hidl服务查询过程分析可知,查询返回的IBase对象是BpHwBase对象。

    hoover架构详细介绍 hil架构_Java_08

    这里接着通过hardware::toBinder接口将IBase对象转换为binder对象,其实就是从BpHwBase中拿到其成员变量mRemote中的BpHwBinder对象,最后在JNI层将调用JHwRemoteBinder::NewObject()函数来创建一个Java层HwRemoteBinder对象。

    frameworks\base\core\jni\android_os_HwBinder.cpp

    1. jobject JHwRemoteBinder::NewObject(  
    2.         JNIEnv *env, const sp<hardware::IBinder> &binder) {  
    3.     ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));  
    4.   
    5.     // XXX Have to look up the constructor here because otherwise that static  
    6.     // class initializer isn’t called and gProxyOffsets.constructID is undefined :(  
    7.   
    8.     jmethodID constructID = GetMethodIDOrDie(env, clazz.get(), ”<init>”, “()V”);  
    9.   
    10.     jobject obj = env->NewObject(clazz.get(), constructID);  
    11.     JHwRemoteBinder::GetNativeContext(env, obj)->setBinder(binder);  
    12.   
    13.     return obj;  
    14. }

    首先调用HwRemoteBinder的构造函数创建一个HwRemoteBinder对象。

    frameworks\base\core\java\android\os\HwRemoteBinder.java

    1. static {  
    2.     long freeFunction = native_init();  
    3.   
    4.     sNativeRegistry = new NativeAllocationRegistry(  
    5.             HwRemoteBinder.class.getClassLoader(),  
    6.             freeFunction,  
    7.             128 / size /);  
    8. }  
    9.   
    10. public HwRemoteBinder() {  
    11.     native_setup_empty();  
    12.   
    13.     sNativeRegistry.registerNativeAllocation(  
    14.             this,  
    15.             mNativeContext);  
    16. }

    首先将执行静态代码块,做必要的初始化,然后执行对象的构造函数。

    frameworks\base\core\jni\android_os_HwRemoteBinder.cpp

    1. static jlong JHwRemoteBinder_native_init(JNIEnv env) {  
    2.     JHwRemoteBinder::InitClass(env);  
    3.   
    4.     return reinterpret_cast<jlong>(&releaseNativeContext);  
    5. }  
    6.   
    7. static void JHwRemoteBinder_native_setup_empty(JNIEnv *env, jobject thiz) {  
    8.     sp<JHwRemoteBinder> context =  
    9.         new JHwRemoteBinder(env, thiz, NULL / service */);  
    10.   
    11.     JHwRemoteBinder::SetNativeContext(env, thiz, context);  
    12. }

    1. JHwRemoteBinder::JHwRemoteBinder(  
    2.         JNIEnv *env, jobject thiz, const sp<hardware::IBinder> &binder)  
    3.     : mBinder(binder) {  
    4.     mDeathRecipientList = new HwBinderDeathRecipientList();  
    5.     jclass clazz = env->GetObjectClass(thiz);  
    6.     CHECK(clazz != NULL);  
    7.   
    8.     mObject = env->NewWeakGlobalRef(thiz);  
    9. }  
    JHwRemoteBinder::JHwRemoteBinder( 
    
            JNIEnv *env, jobject thiz, const sp<hardware::IBinder> &binder) 
    
        : mBinder(binder) { 
    
        mDeathRecipientList = new HwBinderDeathRecipientList(); 
    
        jclass clazz = env->GetObjectClass(thiz); 
    
        CHECK(clazz != NULL);

    这里在JNI层创建一个JHwRemoteBinder对象,并将其对象指针保存到Java层HwRemoteBinder的mNativeContext变量中。

    1. sp<JHwRemoteBinder> JHwRemoteBinder::SetNativeContext(  
    2.         JNIEnv env, jobject thiz, const sp<JHwRemoteBinder> &context) {  
    3.     sp<JHwRemoteBinder> old =  
    4.         (JHwRemoteBinder )env->GetLongField(thiz, gProxyOffsets.contextID);  
    5.   
    6.     if (context != NULL) {  
    7.         context->incStrong(NULL / id /);  
    8.     }  
    9.   
    10.     if (old != NULL) {  
    11.         old->decStrong(NULL / id /);  
    12.     }  
    13.   
    14.     env->SetLongField(thiz, gProxyOffsets.contextID, (long)context.get());  
    15.   
    16.     return old;  
    17. }  
    sp<JHwRemoteBinder> JHwRemoteBinder::SetNativeContext( 
    
            JNIEnv *env, jobject thiz, const sp<JHwRemoteBinder> &context) { 
    
        sp<JHwRemoteBinder> old = 
    
            (JHwRemoteBinder *)env->GetLongField(thiz, gProxyOffsets.contextID);

    到此就完成了HwRemoteBinder对象的创建过程,接着会将查询到的IBinder保存到JHwRemoteBinder的mBinder变量中。

    JHwRemoteBinder::GetNativeContext(env,obj)->setBinder(binder);

    [cpp] view plain copy

    1. void JHwRemoteBinder::setBinder(const sp<hardware::IBinder> &binder) {  
    2.     mBinder = binder;  
    3. }  

    这些对象之间的关系如下图所示:

    hoover架构详细介绍 hil架构_java_09

    因此Java hidl服务查询最终得到一个HwRemoteBinder对象。

    接口转换过程

     

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


    1. / package private / static IWifi asInterface(android.os.IHwBinder binder) {  
    2.     if (binder == null) {  
    3.         return null;  
    4.     }  
    5.   
    6.     android.os.IHwInterface iface =  
    7.             binder.queryLocalInterface(kInterfaceName);  
    8.   
    9.     if ((iface != null) && (iface instanceof IWifi)) {  
    10.         return (IWifi)iface;  
    11.     }  
    12.   
    13.     IWifi proxy = new IWifi.Proxy(binder);  
    14.   
    15.     try {  
    16.         for (String descriptor : proxy.interfaceChain()) {  
    17.             if (descriptor.equals(kInterfaceName)) {  
    18.                 return proxy;  
    19.             }  
    20.         }  
    21.     } catch (android.os.RemoteException e) {  
    22.     }  
    23.   
    24.     return null;  
    25. }


    这里在HwRemoteBinder对象的基础上包裹了一层与业务相关的Proxy对象,这样业务和传输分离,通过代理方式实现IPC调用。

    hoover架构详细介绍 hil架构_hoover架构详细介绍_10

    到此Treble架构下的hwBinder实现过程就基本介绍完成。