AndroidO Treble架构下HIDL服务Java框架实现

前面介绍了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服务注册,如下所示:

  1. XXXImp mXXXImp = new XXXImp();  
  2. 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

  1. public HwBinder() {  
  2.     native_setup();  
  3.   
  4.     sNativeRegistry.registerNativeAllocation(  
  5.             this,  
  6.             mNativeContext);  
  7. }  
public HwBinder() {
    native_setup();

    sNativeRegistry.registerNativeAllocation(
            this,
            mNativeContext);
}
  1. static {  
  2.     long freeFunction = native_init();  
  3.   
  4.     sNativeRegistry = new NativeAllocationRegistry(  
  5.             HwBinder.class.getClassLoader(),  
  6.             freeFunction,  
  7.             128 /* size */);  
  8. }  
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

  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. }  
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变量中。

  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. }  
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

  1. public native final void registerService(String serviceName)  
  2.         throws RemoteException;  
public native final void registerService(String serviceName)
        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. }  
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中。

  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. }  
sp<JHwBinder> JHwBinder::GetNativeBinder(
        JNIEnv *env, jobject thiz) {
    JHwBinderHolder *holder =
        reinterpret_cast<JHwBinderHolder *>(
                env->GetLongField(thiz, gFields.contextID));

    return holder->get(env, thiz);
}
  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. }  
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

  1. BpHwBase::BpHwBase(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)  
  2.         : BpInterface<IBase>(_hidl_impl),  
  3.           ::android::hardware::details::HidlInstrumentor([email protected]“IBase”) {  
  4. }  
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服务查询过程

  1.   
 
 

既然有注册,那么肯定存在服务查询,那么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([email protected]::IWifi”,serviceName));  
  3. }  
  4.   
  5. public static IWifi getService() throws android.os.RemoteException {  
  6.     return IWifi.asInterface(android.os.HwBinder.getService([email protected]::IWifi”,“default”));  
  7. }  
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

  1. public static native final IHwBinder getService(  
  2.         String iface,  
  3.         String serviceName)  
  4.     throws RemoteException, NoSuchElementException;  
public static native final IHwBinder getService(
        String iface,
        String serviceName)
    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. }  
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;





猜你喜欢

转载自blog.csdn.net/marshal_zsx/article/details/80293232