上一篇我们从Binder在系统native层的服务管理与提供机制,它与Framework的native层的实现大不相同,但是实现思想是一致的,都是需要借助Binder驱动来实现服务的管理与跨进程使用。只不过,由于业务层需要导致实现上的不同,比如HAL层的Binder框架并没有将通讯和业务绞和起来,所以在业务逻辑处理上更为复杂,当然复杂是为了更好的适应业务需求。那么我们不妨回到Java层看看Java的HwBinder是如何为用户提供便利操作的,首先我们来看基本的HwBinder在Java层的框架。
1. Binder顶层协议
public interface IHwBinder {
// These MUST match their corresponding libhwbinder/IBinder.h definition !!!
public static final int FIRST_CALL_TRANSACTION = 1;
public static final int FLAG_ONEWAY = 1;
public void transact( //通讯操作函数
int code, HwParcel request, HwParcel reply, int flags)
throws RemoteException;
public IHwInterface queryLocalInterface(String descriptor); //查询服务描述符
.....
}
HwRemoteBinder 实现了 IHwBinder 接口
public class HwRemoteBinder implements IHwBinder {
private static final String TAG = "HwRemoteBinder";
private static final NativeAllocationRegistry sNativeRegistry;
public HwRemoteBinder() {
native_setup_empty();
sNativeRegistry.registerNativeAllocation(
this,
mNativeContext);
}
@Override
public IHwInterface queryLocalInterface(String descriptor) {
return null; //返回为空
}
@Override
public native final void transact( //未实现
int code, HwParcel request, HwParcel reply, int flags)
throws RemoteException;
}
......
private static native final long native_init();
private native final void native_setup_empty();
......
private long mNativeContext;
}
HwBinder 实现了 IHwBinder 接口
public abstract class HwBinder implements IHwBinder {
private static final String TAG = "HwBinder";
private static final NativeAllocationRegistry sNativeRegistry;
public HwBinder() {
native_setup();
sNativeRegistry.registerNativeAllocation(
this,
mNativeContext);
}
@Override
public final native void transact( //未实现
int code, HwParcel request, HwParcel reply, int flags)
throws RemoteException;
public abstract void onTransact(// 新增
int code, HwParcel request, HwParcel reply, int flags)
throws RemoteException;
public native final void registerService(String serviceName)
throws RemoteException;
public static native final IHwBinder getService(
String iface,
String serviceName)
throws RemoteException, NoSuchElementException;
// Returns address of the "freeFunction".
private static native final long native_init();
private native final void native_setup();
......
private long mNativeContext;
}
IHwInterface 接口
public interface IHwInterface {
public IHwBinder asBinder();
}
在 frameworks\base\core\jni\android_os_HwBinder.cpp 文件中可以看到注册表
static JNINativeMethod gMethods[] = {
{ "native_init", "()J", (void *)JHwBinder_native_init },
{ "native_setup", "()V", (void *)JHwBinder_native_setup },
{ "transact",
"(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V",
(void *)JHwBinder_native_transact },
{ "registerService", "(Ljava/lang/String;)V",
(void *)JHwBinder_native_registerService },
{ "getService", "(Ljava/lang/String;Ljava/lang/String;)L" PACKAGE_PATH "/IHwBinder;",
(void *)JHwBinder_native_getService },
};
static jlong JHwBinder_native_init(JNIEnv *env) {
JHwBinder::InitClass(env);
return reinterpret_cast<jlong>(&releaseNativeContext);
}
初始化类
void JHwBinder::InitClass(JNIEnv *env) {
ScopedLocalRef<jclass> clazz(
env, FindClassOrDie(env, CLASS_PATH));
gFields.contextID =
GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");
gFields.onTransactID =
GetMethodIDOrDie(
env,
clazz.get(),
"onTransact",
"(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V");
}
static void JHwBinder_native_setup(JNIEnv *env, jobject thiz) {
sp<JHwBinder> context = new JHwBinder(env, thiz);
JHwBinder::SetNativeContext(env, thiz, context);
}
设置上下文
sp<JHwBinder> JHwBinder::SetNativeContext(
JNIEnv *env, jobject thiz, const sp<JHwBinder> &context) {
sp<JHwBinder> old =
(JHwBinder *)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;
}
获取服务流程
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;
.......
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());
//查询Binder类型
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< //转换为Binder
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); //创建BpBinder对象并返回
}
可以看到获取服务最终还是需要调用native层的Binder框架来处理,这一点可Framework层中的Binder(Java)设计思想是一致的
2. Power.hal生成的服务接口
由于定义了.hal文件,通过编译会生成对响应的服务代码,out/target/gen/JAVA_LIBRARIES/android.hardware.power-V1.0-java_intermediates目录下IPower.java文件
public static IPower getService(String serviceName) throws android.os.RemoteException {
return IPower.asInterface(android.os.HwBinder.getService("[email protected]::IPower",serviceName));
}
static IPower asInterface(android.os.IHwBinder binder) { //查询
if (binder == null) {
return null;
}
android.os.IHwInterface iface =
binder.queryLocalInterface(kInterfaceName);
if ((iface != null) && (iface instanceof IPower)) {
return (IPower)iface;
}
IPower proxy = new IPower.Proxy(binder); //Proxy内部类
try {
for (String descriptor : proxy.interfaceChain()) {
if (descriptor.equals(kInterfaceName)) {
return proxy;
}
}
} catch (android.os.RemoteException e) {
}
return null;
}
内部类,返回远程Binder代理对象
public static final class Proxy implements IPower {
private android.os.IHwBinder mRemote;
public Proxy(android.os.IHwBinder remote) {
mRemote = java.util.Objects.requireNonNull(remote);
}
@Override
public android.os.IHwBinder asBinder() {
return mRemote;
}
......
}
内部类,通过Stub调用
public static abstract class Stub extends android.os.HwBinder implements IBase {
@Override
public android.os.IHwBinder asBinder() {
return this;
}
@Override
public final java.util.ArrayList<String> interfaceChain() {
return new java.util.ArrayList<String>(java.util.Arrays.asList(
IBase.kInterfaceName));
}
@Override
public final String interfaceDescriptor() {
return IBase.kInterfaceName;
}
......
@Override
public void onTransact(int _hidl_code, android.os.HwParcel _hidl_request, final android.os.HwParcel _hidl_reply, int _hidl_flags)
throws android.os.RemoteException {
}
}
由此可以看出HIDL生成的服务代码与AIDL是相似的,继续看会发现IPower继承了android.hidl.base.V1_0.IBase.java, IBase继承自android.os.IHwInterface.java
本篇跟踪了Java层仍然需要通过native层的Binder框架来使用Hw层服务的,流程和Framework层的Binder调用大致一样,较为简单,今天就到此为止。