AndroidQ 从app到驱动 第五章 编写JNI层完成HelloService与Hal层的对接

前面四篇文章,分别介绍了驱动添加,hal层添加,HelloService添加,以及上层测试应用的添加,这里进行我们的最后一步,完成HelloService与Hal层的对接。

AndroidQ 从app到驱动 第一章 编写Linux内核驱动程序

AndroidQ 从app到驱动 第二章 添加HAL层,先打通JNI层到驱动的访问

AndroidQ 从app到驱动 第三章 SystemServer服务中添加 HelloService

AndroidQ 从app到驱动 第四章 编写app验证新添加的helloservice是否正常

AndroidQ 从app到驱动 第五章 编写JNI层完成HelloService与Hal层的对接

AndroidQ 从app到驱动 第六章 从app到驱动的所有的代码整理

按照惯例,先上图,介绍修改点。图片只关注红色新添加的部分。

AndroidQ 从app到驱动 第五章 编写JNI层完成HelloService与Hal层的对接_第1张图片

截图显示,这里修改了三个文件,新添加了一个文件,修改内容比较少,而且修改的HelloService.java 是之前新添加的文件。下面依次介绍下这几个文件的修改点。

1)frameworks/base/services/core/java/com/android/server/HelloService.java 的修改,这里添加了对JNI层接口的访问,时间接口对接。AndroidQ 从app到驱动 第五章 编写JNI层完成HelloService与Hal层的对接_第2张图片

2)frameworks/base/services/core/jni/Android.bp的修改。这里的修改使得新添加的app文件能够参与编译。

3)frameworks/base/services/core/jni/onload.cpp 的修改,这里添加jni层接口的初始化部分,使得我们新添加的JNI层接口在系统初始化的时候能够正常加载到。AndroidQ 从app到驱动 第五章 编写JNI层完成HelloService与Hal层的对接_第3张图片

 4)frameworks/base/services/core/jni/com_android_server_HelloService.cpp 文件的内容。这里是JNI层的具体实现,代码结构比较简单,就不做解释了。

/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define LOG_TAG "Hello_JNI"
#include "jni.h"
#include "core_jni_helpers.h"

#include 
#include 
#include 
#include 

namespace {

struct hello_device* hello_device = NULL;

 static inline int hello_device_open(const hw_module_t* module, struct hello_device** device) {
     return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
 }

static jint HelloServiceInit(JNIEnv* env, jobject /* clazz */) {
	ALOGE("com_android_server_HelloService HelloServiceInit");
	const hw_module_t *hw_module = NULL;
    ALOGE("Hello JNI: initializing......");
    if(hw_get_module(HELLO_HARDWARE_MODULE_ID, &hw_module) == 0) {
        ALOGE("Hello JNI: hello Stub found.");
        if(hello_device_open(hw_module, &hello_device) == 0) {
          ALOGE("Hello JNI: hello device is open.");
          return 0;
        }
        ALOGE("Hello JNI: failed to open hello device.");
        return -1;
    }
    ALOGE("Hello JNI: failed to get hello stub hw_module.");
    return -1;
}


static void HelloServiceNativeSetVal(JNIEnv* env, jobject clazz,jstring nativeValue) {
	ALOGE("com_android_server_HelloService HelloServiceNativeSetVal");
    if(!hello_device) {
      ALOGI("Hello JNI: hello_device is not open.");
      return;
    }

	const char* local_value = (nativeValue) ? env->GetStringUTFChars(nativeValue, NULL) : NULL;
	ALOGE("com_android_server_HelloService HelloServiceNativeSetVal local_value = %s",local_value);
    hello_device->write_string(hello_device, local_value);
    ALOGI("Hello JNI: write string %s to Hello hello_device.", local_value);
	env->ReleaseStringUTFChars(nativeValue, local_value);
}

static jstring HelloServiceNativeGetVal(JNIEnv* env,jobject clazz) {
    ALOGE("com_android_server_HelloService HelloServiceNativeGetVal");
    if(!hello_device) {
       ALOGE("Hello JNI: hello_device is not open.");  
       return NULL;  
     }  
     char read_str[50];
     hello_device->read_string(hello_device,read_str);  
     ALOGE("Hello JNI: read string %s from Hello hello_device.", read_str); 
	 jstring result = (env)->NewStringUTF(read_str);
     return result;
}

static const JNINativeMethod methods[] = {
    {"HelloServiceInit", "()I", (void*) HelloServiceInit},
    {"HelloServiceNativeSetVal", "(Ljava/lang/String;)V",(void*) HelloServiceNativeSetVal},
    {"HelloServiceNativeGetVal", "()Ljava/lang/String;",(void*) HelloServiceNativeGetVal},
};

}

namespace android {

int register_android_server_HelloService(JNIEnv *env) {
    return jniRegisterNativeMethods(env, "com/android/server/HelloService", methods, NELEM(methods));
}

}

 至此,添加JNI层需要修改的地方就修改完毕了,剩下的就是编译验证。

验证结果如下:

1)系统初始化时候的log

06-02 19:34:34.075124   671   671 E Hello_JNI: com_android_server_HelloService HelloServiceInit
06-02 19:34:34.075183   671   671 E Hello_JNI: Hello JNI: initializing......
06-02 19:34:34.090683   671   671 E Hello_JNI: Hello JNI: hello Stub found.
06-02 19:34:34.090891   671   671 E Legacy HelloHAL: Hello: hello_device_open name = hello
06-02 19:34:34.091773   671   671 E Legacy HelloHAL: Hello: open /dev/hello successfully.
06-02 19:34:34.091888   671   671 E Hello_JNI: Hello JNI: hello device is open.

log显示,HelloService能够正常调用到JNI层,JNI层调用Hal层正常,Hal层可以正常打开驱动。(这里由于HelloService的log在另一个log文件中,因此就没有贴出来。mtk的log,区分system log跟main log)

2)测试应用执行的log

06-02 19:38:07.288  2598  2598 I HelloServiceTest: HelloService TEST setVal HELLO to drivers
06-02 19:38:07.288  2598  2598 E HelloManager: HelloManager setVal
06-02 19:38:07.289   660  1987 I HelloService: setVal value = HELLO
06-02 19:38:07.289   660  1987 E Hello_JNI: com_android_server_HelloService HelloServiceNativeSetVal
06-02 19:38:07.289   660  1987 E Hello_JNI: com_android_server_HelloService HelloServiceNativeSetVal local_value = HELLO
06-02 19:38:07.289   660  1987 E Legacy HelloHAL: Hello:write string: HELLO
06-02 19:38:07.289   660  1987 I Hello_JNI: Hello JNI: write string HELLO to Hello hello_device.

06-02 19:38:07.290  2598  2598 E HelloManager: HelloManager getVal
06-02 19:38:07.291   660  1987 I HelloService: getVal 
06-02 19:38:07.291   660  1987 E Hello_JNI: com_android_server_HelloService HelloServiceNativeGetVal
06-02 19:38:07.291   660  1987 E Legacy HelloHAL: Hello:read hello_read_string
06-02 19:38:07.291   660  1987 E Hello_JNI: Hello JNI: read string HELLO from Hello hello_device.
06-02 19:38:07.291  2598  2598 I HelloServiceTest: HelloService TEST getVal = HELLO


kernel的log
<1>[   59.096713]  (0)[1987:Binder:660_D]hello_write AAAAAAAAAAAAAA.
<1>[   59.096743]  (0)[1987:Binder:660_D]hello_write BBBBBBBBBBBBBBB.
<1>[   59.096750]  (0)[1987:Binder:660_D]hello_write CCCCCCCCCCCCCC.
<1>[   59.098570]  (0)[1987:Binder:660_D]hello_read.
<1>[   59.098600]  (0)[1987:Binder:660_D]hello_read AAAAAAAAAAAAAA.
<1>[   59.098606]  (0)[1987:Binder:660_D]hello_read BBBBBBBBBBBBBBB.
<1>[   59.098612]  (0)[1987:Binder:660_D]hello_read CCCCCCCCCCCCCCCCC.

log显示,执行结果正常,至此,从app到驱动的所有流程就调通了,当然这个仅仅只是入门,添加的这些仅仅用于学习测试用,当然会有各种问题欢迎评论,讨论研究!

 

你可能感兴趣的:(Android)