1. 程式人生 > >AndroidO Treble架構下HIDL服務Java框架實現

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服務註冊,如下所示:

[java] view plain copy print?
  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

[java] view plain copy print?
  1. public HwBinder() {  
  2.     native_setup();  
  3.     sNativeRegistry.registerNativeAllocation(  
  4.             this,  
  5.             mNativeContext);  
  6. }  
public HwBinder() {
    native_setup();

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

[cpp] view plain copy print?
  1. static jlong JHwBinder_native_init(JNIEnv *env) {  
  2.     JHwBinder::InitClass(env);  
  3.     returnreinterpret_cast<jlong>(&releaseNativeContext);  
  4. }  
  5. staticvoid JHwBinder_native_setup(JNIEnv *env, jobject thiz) {  
  6.     sp<JHwBinderHolder> context = new JHwBinderHolder;  
  7.     JHwBinder::SetNativeContext(env, thiz, context);  
  8. }  
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變數中。

[cpp] view plain copy print?
  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.     if (context != NULL) {  
  6.         context->incStrong(NULL /* id */);  
  7.     }  
  8.     if (old != NULL) {  
  9.         old->decStrong(NULL /* id */);  
  10.     }  
  11.     env->SetLongField(thiz, gFields.contextID, (long)context.get());  
  12.     return old;  
  13. }  
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

[java] view plain copy print?
  1. publicnativefinalvoid registerService(String serviceName)  
  2.         throws RemoteException;  
public native final void registerService(String serviceName)
        throws RemoteException;

frameworks\base\core\jni\android_os_HwBinder.cpp

[cpp] view plain copy print?
  1. staticvoid 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.     constchar *serviceName = env->GetStringUTFChars(serviceNameObj, NULL);  
  10.     if (serviceName == NULL) {  
  11.         return;  // XXX exception already pending?
  12.     }  
  13.     sp<hardware::IBinder> binder = JHwBinder::GetNativeBinder(env, thiz);  
  14.     /* TODO(b/33440494) this is not right */
  15.     sp<hidl::base::V1_0::IBase> base = new hidl::base::V1_0::BpHwBase(binder);  
  16.     auto manager = hardware::defaultServiceManager();  
  17.     if (manager == nullptr) {  
  18.         LOG(ERROR) << ”Could not get hwservicemanager.”;  
  19.         signalExceptionForError(env, UNKNOWN_ERROR, true/* canThrowRemoteException */);  
  20.         return;  
  21.     }  
  22.     Return<bool> ret = manager->add(serviceName, base);  
  23.     env->ReleaseStringUTFChars(serviceNameObj, serviceName);  
  24.     serviceName = NULL;  
  25.     bool ok = ret.isOk() && ret;  
  26.     if (ok) {  
  27.         LOG(INFO) << ”Starting thread pool.”;  
  28.         ::android::hardware::ProcessState::self()->startThreadPool();  
  29.     }  
  30.     signalExceptionForError(env, (ok ? OK : UNKNOWN_ERROR), true/* canThrowRemoteException */);  
  31. }  
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中。

[cpp] view plain copy print?
  1. sp<JHwBinder> JHwBinder::GetNativeBinder(  
  2.         JNIEnv *env, jobject thiz) {  
  3.     JHwBinderHolder *holder =  
  4.         reinterpret_cast<JHwBinderHolder *>(  
  5.                 env->GetLongField(thiz, gFields.contextID));  
  6.     return holder->get(env, thiz);  
  7. }  
sp<JHwBinder> JHwBinder::GetNativeBinder(
        JNIEnv *env, jobject thiz) {
    JHwBinderHolder *holder =
        reinterpret_cast<JHwBinderHolder *>(
                env->GetLongField(thiz, gFields.contextID));

    return holder->get(env, thiz);
}
[cpp] view plain copy print?
  1. sp<JHwBinder> get(JNIEnv *env, jobject obj) {  
  2.     Mutex::Autolock autoLock(mLock);  
  3.     sp<JHwBinder> binder = mBinder.promote();  
  4.     if (binder == NULL) {  
  5.         binder = new JHwBinder(env, obj);  
  6.         mBinder = binder;  
  7.     }  
  8.     return binder;  
  9. }  
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

[cpp] view plain copy print?
  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服務查詢過程

[java] view plain copy print?

既然有註冊,那麼肯定存在服務查詢,那麼Client程序如何查詢這些執行在Server程序端的Java hidl服務呢?

out/target/common/gen/JAVA_LIBRARIES/android.hardware.wifi-V1.1-java_intermediates/android/hardware/wifi/V1_1/IWifi.java

[java] view plain copy print?
  1. publicstatic IWifi getService(String serviceName) throws android.os.RemoteException {  
  2.     return IWifi.asInterface(android.os.HwBinder.getService([email protected]::IWifi”,serviceName));  
  3. }  
  4. publicstatic IWifi getService() throws android.os.RemoteException {  
  5.     return IWifi.asInterface(android.os.HwBinder.getService([email protected]::IWifi”,“default”));  
  6. }  
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

[java] view plain copy print?
  1. publicstaticnativefinal 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

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

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

[java] view plain copy print?
  1. static {  
  2.     long freeFunction = native_init();  
  3.     sNativeRegistry = new NativeAllocationRegistry(  
  4.             HwRemoteBinder.class.getClassLoader(),  
  5.             freeFunction,  
  6.             128/ size /);  
  7. }  
  8. public HwRemoteBinder() {  
  9.     native_setup_empty();  
  10.     sNativeRegistry.registerNativeAllocation(  
  11.             this,  
  12.             mNativeContext);  
  13. }  
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

[cpp] view plain copy print?
  1. static jlong JHwRemoteBinder_native_init(JNIEnv env) {  
  2.     JHwRemoteBinder::InitClass(env);  
  3.     returnreinterpret_cast<jlong>(&releaseNativeContext);  
  4. }  
  5. staticvoid JHwRemoteBinder_native_setup_empty(JNIEnv *env, jobject thiz) {  
  6.     sp<JHwRemoteBinder> context =  
  7.         new JHwRemoteBinder(env, thiz, NULL / service */);  
  8.     JHwRemoteBinder::SetNativeContext(env, thiz, context);  
  9. }  
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);

}

[cpp] view plain copy print?
  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.     mObject = env->NewWeakGlobalRef(thiz);  
  8. }  
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變數中。

[cpp] view plain copy print?
  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.     if (context != NULL) {  
  6.         context->incStrong(NULL / id /);  
  7.     }  
  8.     if (old != NULL) {  
  9.         old->decStrong(NULL / id /);  
  10.     }  
  11.     env->SetLongField(thiz, gProxyOffsets.contextID, (long)context.get());  
  12.     return old;  
  13. }  
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);

[cpp] view plain copy print?
  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函式完成。

[java] view plain copy print?
  1. / package private /static IWifi asInterface(android.os.IHwBinder binder) {  
  2.     if (binder == null) {  
  3.         returnnull;  
  4.     }  
  5.     android.os.IHwInterface iface =  
  6.             binder.queryLocalInterface(kInterfaceName);  
  7.     if ((iface != null) && (iface instanceof IWifi)) {  
  8.         return (IWifi)iface;  
  9.     }  
  10.     IWifi proxy = new IWifi.Proxy(binder);  
  11.     try {  
  12.         for (String descriptor : proxy.interfaceChain()) {  
  13.             if (descriptor.equals(kInterfaceName)) {  
  14.                 return proxy;  
  15.             }  
  16.         }  
  17.     } catch (android.os.RemoteException e) {  
  18.     }  
  19.     returnnull;  
  20. }  
/* 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實現過程就基本介紹完成。