前面介绍了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”);
这样就完成了一个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. }
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他们的类继承图如下:
红线标识了这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;
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的引用。
从进程空间角度来看Java hidl服务注册,如下:
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对象。
这里接着通过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
- 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. }
这里在HwRemoteBinder对象的基础上包裹了一层与业务相关的Proxy对象,这样业务和传输分离,通过代理方式实现IPC调用。
到此Treble架构下的hwBinder实现过程就基本介绍完成。