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?- 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);
}
[java] view plain copy print?- 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
[cpp] view plain copy print?- static jlong JHwBinder_native_init(JNIEnv *env) {
- JHwBinder::InitClass(env);
- returnreinterpret_cast<jlong>(&releaseNativeContext);
- }
- staticvoid 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變數中。
[cpp] view plain copy print?- 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
[java] view plain copy print?- publicnativefinalvoid registerService(String serviceName)
- throws RemoteException;
public native final void registerService(String serviceName)
throws RemoteException;
frameworks\base\core\jni\android_os_HwBinder.cpp
[cpp] view plain copy print?- staticvoid JHwBinder_native_registerService(
- JNIEnv *env,
- jobject thiz,
- jstring serviceNameObj) {
- if (serviceNameObj == NULL) {
- jniThrowException(env, ”java/lang/NullPointerException”, NULL);
- return;
- }
- constchar *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);
}
[cpp] view plain copy print?- 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
[cpp] view plain copy print?- 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服務查詢過程
[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?- publicstatic IWifi getService(String serviceName) throws android.os.RemoteException {
- return IWifi.asInterface(android.os.HwBinder.getService(“[email protected]::IWifi”,serviceName));
- }
- publicstatic 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
[java] view plain copy print?- publicstaticnativefinal 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
[cpp] view plain copy print?- 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;
- }
- constchar *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());
- constchar *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__
- constchar* testingOverride = std::getenv(“TREBLE_TESTING_OVERRIDE”);
- constbool vintfLegacy = (transport == IServiceManager::Transport::EMPTY)
- && testingOverride && !strcmp(testingOverride, ”true”);
- #else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__
- constbool vintfLegacy = false;
- #endif // __ANDROID_DEBUGGABLE__
- #else // not __ANDROID_TREBLE__
- constbool 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;
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);
}
首先檢查當前查詢的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?- 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(), ”<init>”, “()V”);
- jobject obj = env->NewObject(clazz.get(), constructID);
- JHwRemoteBinder::GetNativeContext(env, obj)->setBinder(binder);
- return obj;
- }
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(), "<init>", "()V");
jobject obj = env->NewObject(clazz.get(), constructID);
JHwRemoteBinder::GetNativeContext(env, obj)->setBinder(binder);
return obj;
}
首先呼叫HwRemoteBinder的建構函式建立一個HwRemoteBinder物件。
frameworks\base\core\java\android\os\HwRemoteBinder.java
[java] view plain copy print?- static {
- long freeFunction = native_init();
- sNativeRegistry = new NativeAllocationRegistry(
- HwRemoteBinder.class.getClassLoader(),
- freeFunction,
- 128/ size /);
- }
- public HwRemoteBinder() {
- native_setup_empty();
- sNativeRegistry.registerNativeAllocation(
- this,
- mNativeContext);
- }
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?- static jlong JHwRemoteBinder_native_init(JNIEnv env) {
- JHwRemoteBinder::InitClass(env);
- returnreinterpret_cast<jlong>(&releaseNativeContext);
- }
- staticvoid JHwRemoteBinder_native_setup_empty(JNIEnv *env, jobject thiz) {
- sp<JHwRemoteBinder> context =
- new JHwRemoteBinder(env, thiz, NULL / service */);
- JHwRemoteBinder::SetNativeContext(env, thiz, context);
- }
static jlong JHwRemoteBinder_native_init(JNIEnv *env) {
JHwRemoteBinder::InitClass(env);
return reinterpret_cast<jlong>(&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?- 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->NewWeakGlobalRef(thiz);
- }
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->NewWeakGlobalRef(thiz);
}
這裡在JNI層建立一個JHwRemoteBinder物件,並將其物件指標儲存到Java層HwRemoteBinder的mNativeContext變數中。
[cpp] view plain copy print?- 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->incStrong(NULL / id /);
- }
- if (old != NULL) {
- old->decStrong(NULL / id /);
- }
- env->SetLongField(thiz, gProxyOffsets.contextID, (long)context.get());
- return old;
- }
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->incStrong(NULL /* id */);
}
if (old != NULL) {
old->decStrong(NULL /* id */);
}
env->SetLongField(thiz, gProxyOffsets.contextID, (long)context.get());
return old;
}
到此就完成了HwRemoteBinder物件的建立過程,接著會將查詢到的IBinder儲存到JHwRemoteBinder的mBinder變數中。
JHwRemoteBinder::GetNativeContext(env,obj)->setBinder(binder);
[cpp] view plain copy print?- void JHwRemoteBinder::setBinder(const sp<hardware::IBinder> &binder) {
- mBinder = binder;
- }
void JHwRemoteBinder::setBinder(const sp<hardware::IBinder> &binder) {
mBinder = binder;
}
這些物件之間的關係如下圖所示:
因此Java hidl服務查詢最終得到一個HwRemoteBinder物件。
介面轉換過程
通過服務查詢得到HwRemoteBinder物件,這個只是傳輸層面的物件而已,需要轉換為業務層面的物件,這個是由IXXX.asInterface函式完成。
[java] view plain copy print?- / package private /static IWifi asInterface(android.os.IHwBinder binder) {
- if (binder == null) {
- returnnull;
- }
- android.os.IHwInterface iface =
- binder.queryLocalInterface(kInterfaceName);
- if ((iface != null) && (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) {
- }
- returnnull;
- }
/* package private */ static IWifi asInterface(android.os.IHwBinder binder) {
if (binder == null) {
return null;
}
android.os.IHwInterface iface =
binder.queryLocalInterface(kInterfaceName);
if ((iface != null) && (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實現過程就基本介紹完成。