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对象。

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. }  
BpHwBase::BpHwBase(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)
        : BpInterface<IBase>(_hidl_impl),
          ::android::hardware::details::HidlInstrumentor("android.hidl.base@1.0", "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(“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. }  
public static IWifi getService(String serviceName) throws android.os.RemoteException {
    return IWifi.asInterface(android.os.HwBinder.getService("android.hardware.wifi@1.1::IWifi",serviceName));
}

public static IWifi getService() throws android.os.RemoteException {
    return IWifi.asInterface(android.os.HwBinder.getService("android.hardware.wifi@1.1::IWifi","default"));
}

这里首先调用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;  
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;





ifdef ANDROID_TREBLE

ifdef ANDROID_DEBUGGABLE

const char* testingOverride = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY)
        &amp;&amp; testingOverride &amp;&amp; !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 &amp;&amp; !vintfLegacy) {
    LOG(ERROR) &lt;&lt; "service " &lt;&lt; ifaceName &lt;&lt; " declares transport method "
               &lt;&lt; toString(transport) &lt;&lt; " but framework expects hwbinder.";
    signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
    return NULL;
}

Return&lt;sp&lt;hidl::base::V1_0::IBase&gt;&gt; ret = manager-&gt;get(ifaceNameHStr, serviceNameHStr);

if (!ret.isOk()) {
    signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
    return NULL;
}

sp&lt;hardware::IBinder&gt; service = hardware::toBinder&lt;
        hidl::base::V1_0::IBase, hidl::base::V1_0::BpHwBase&gt;(ret);

if (service == NULL) {
    signalExceptionForError(env, NAME_NOT_FOUND);
    return NULL;
}

LOG(INFO) &lt;&lt; "Starting thread pool.";
::android::hardware::ProcessState::self()-&gt;startThreadPool();

return JHwRemoteBinder::NewObject(env, service);

}

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


这里接着通过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. }  
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(), "&lt;init&gt;", "()V");

jobject obj = env-&gt;NewObject(clazz.get(), constructID);
JHwRemoteBinder::GetNativeContext(env, obj)-&gt;setBinder(binder);

return obj;

}

首先调用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. }  
static { 
long freeFunction = native_init();
sNativeRegistry = new NativeAllocationRegistry(
        HwRemoteBinder.class.getClassLoader(),
        freeFunction,
        128 /* size */);

}

public HwRemoteBinder() {
native_setup_empty();

sNativeRegistry.registerNativeAllocation(
        this,
        mNativeContext);

}

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

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. }  
static jlong JHwRemoteBinder_native_init(JNIEnv *env) { 
JHwRemoteBinder::InitClass(env);
return reinterpret_cast&lt;jlong&gt;(&amp;releaseNativeContext);

}

static void JHwRemoteBinder_native_setup_empty(JNIEnv *env, jobject thiz) {
sp<JHwRemoteBinder> context =
new JHwRemoteBinder(env, thiz, NULL /* service */);

JHwRemoteBinder::SetNativeContext(env, thiz, context);

}

  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);
mObject = env-&gt;NewWeakGlobalRef(thiz);

}

这里在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);
if (context != NULL) {
    context-&gt;incStrong(NULL /* id */);
}

if (old != NULL) {
    old-&gt;decStrong(NULL /* id */);
}

env-&gt;SetLongField(thiz, gProxyOffsets.contextID, (long)context.get());

return old;

}

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

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

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

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

因此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. }  
/* package private */ static IWifi asInterface(android.os.IHwBinder binder) { 
if (binder == null) {
return null;
}
android.os.IHwInterface iface =
        binder.queryLocalInterface(kInterfaceName);

if ((iface != null) &amp;&amp; (iface instanceof IWifi)) {
    return (IWifi)iface;
}

IWifi proxy = new IWifi.Proxy(binder);

try {
    for (String descriptor : proxy.interfaceChain()) {
        if (descriptor.equals(kInterfaceName)) {
            return proxy;
        }
    }
} catch (android.os.RemoteException e) {
}

return null;

}

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


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


  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值