Android8.0 Binder之面向HAL服务(二)

版权声明:未经本人同意,不得转载 https://blog.csdn.net/u013928208/article/details/81301559

上一篇我们从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调用大致一样,较为简单,今天就到此为止。

猜你喜欢

转载自blog.csdn.net/u013928208/article/details/81301559