建立好framework 后 改写JNI文件添加 hal

硬件控制 由HAL实现 而JNI来调用 hal 实现更好的保密性和 代码修改性

android里面对硬件的操作我们一般分为两个文件,一个是JNI文件(向上提供(注册)本地函数,向下加载HAL文件并调用HAL文件的函数),一个是HAL文件(负责访问驱动程序执行具体的硬件操作),这两个文件都是C/C++语言写的,所以JNI来加载HAL的实质就是怎么使用dl_open来加载动态库,android里面对dlopen又做了一层封装,我们使用的是“hw_get_module”这个函数(位于Hardware.c),函数实现过程如下

hw_get_module(“led”);//假设模块名为led,最终由这个模块名转为文件名
代码路径:external\chromium_org\third_party\hwcplus\src\Hardware.c
在这里插入图片描述

调用过程:

模块名(“led”)===>文件名(filename)
hw_get_module
----hw_get_module_by_class(“led”, NULL)
------name = “led”
---------property_get(根据名字获得某个属性值)
---------hw_module_exists(去目录下判断某个模块是否存在)
加载
dlopen(filename)------>(android源目录使用man dlopen查看使用方法)

https://blog.csdn.net/itdo_just/article/details/76187192
这位兄弟写的很好

led_hal.c


#define LOG_TAG "LedHal"

#include <hardware/vibrator.h>
#include <hardware/hardware.h>

#include <cutils/log.h>

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include <hardware/led_hal.h>

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <utils/Log.h>


static int fd;


/** Close this device */
static int led_close(struct hw_device_t* device)
{
	close(fd);
	return 0;
}

static int led_open(struct led_device_t* dev)
{
	fd = open("/dev/leds", O_RDWR);
	ALOGI("led_open : %d", fd);
	if (fd >= 0)
		return 0;
	else
		return -1;
}

static int led_ctrl(struct led_device_t* dev, int which, int status)
{
	int ret = ioctl(fd, status, which);
	ALOGI("led_ctrl : %d, %d, %d", which, status, ret);
	return ret;
}




static struct led_device_t led_dev = {
	.common = {
		.close = led_close,
	},
	.led_open  = led_open,
	.led_ctrl  = led_ctrl,
};

static int led_device_open(const struct hw_module_t* module, const char* id,
        struct hw_device_t** device)
{
	*device = &led_dev;
	return 0;
}


static struct hw_module_methods_t led_module_methods = {
    .open = led_device_open,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
    .id = "led",
    .methods = &led_module_methods,
};



led_hal.h



#ifndef ANDROID_LED_INTERFACE_H
#define ANDROID_LED_INTERFACE_H

#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h>

#include <hardware/hardware.h>

__BEGIN_DECLS

struct led_device_t {
    struct hw_device_t common;

	int (*led_open)(struct led_device_t* dev);
	int (*led_ctrl)(struct led_device_t* dev, int which, int status);
};


__END_DECLS

#endif  // ANDROID_LED_INTERFACE_H


Andriod.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := led.default

# HAL module implementation stored in
# hw/<VIBRATOR_HARDWARE_MODULE_ID>.default.so
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := hardware/libhardware
LOCAL_SRC_FILES := led_hal.c
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := eng

include $(BUILD_SHARED_LIBRARY)


JNI: 重新上传
frameworks/base/services/core/jni/com_android_server_LedService.cpp

HAL: led_hal.h
led_hal.c
把新文件上传到服务器, 所在目录:
hardware/libhardware/include/hardware/led_hal.h
hardware/libhardware/modules/led/led_hal.c
hardware/libhardware/modules/led/Android.mk

Android.mk内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := led.default
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := hardware/libhardware
LOCAL_SRC_FILES := led_hal.c
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := eng

include $(BUILD_SHARED_LIBRARY)

编译:
$ mmm frameworks/base/services
$ mmm hardware/libhardware/modules/led
$ make snod
$ ./gen-img.sh

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android 9.0和10.0的Framework系统API上添加JNI方法需要经过以下步骤: 1. 在Java层调用JNI方法前,需要先创建定义JNI方法的C++文件和对应的头文件。这些文件应该保存在frameworks/native/libs/目录下的对应模块中。例如,如果想要在WebView模块中添加JNI方法,则应该在frameworks/native/libs/webviewchromium/目录下创建文件并进行定义。 2. 编写C++代码实现JNI方法。在代码中,需要采用JNI函数以及Java Native Interface标准库的方法来实现该方法的功能。具体实现过程可以参考Android源码中frameworks/native/libs/input/Input.cpp文件的实现。 3. 在C++代码的头文件中定义JNI方法。为了让Java层正确调用JNI方法,需要在C++文件中定义JNI函数名称、Java包名、Java类名以及方法参数的信息。参考Android源码中frameworks/native/libs/webviewchromium/webviewchromium_jni.h文件。 4. 在Java层调用JNI方法。要调用JNI方法,需要在Java代码中加载C++库。可以使用静态代码块System.loadLibrary("yourlibrary")来加载C++库,并在程序中使用对应的Java扩展头文件。在Java代码中,需要使用JNI函数来调用JNI方法。参考Android源码中frameworks/native/libs/webviewchromium/WebBackForwardList.java文件。 通过以上步骤,即可在Android 9.0和10.0的Framework系统API中添加JNI方法。需要注意的是,添加JNI方法需要遵循JNI标准,使用合适的JNI库函数和API接口,以确保程序代码的正确性和稳定性。 ### 回答2: Android 9.0和10.0的Framework系统API都支持添加JNI方法。 首先,要添加一个JNI方法,您需要在Java中编写该方法的实现,然后在C / C ++中编写对应的本地代码,然后使用JNI将二者连接起来。 为了在Framework添加新的JNI方法,您需要找到Framework源代码中对应的Java类和C ++代码。然后按照以下步骤进行操作: 1. 在Java类中添加新的JNI方法声明,方法名必须与您要添加的本地方法的名称匹配。例如,如果您要添加一个名为newMethod的本地方法,则需要在Java类中声明以下内容: ```java public native void newMethod(int arg1, String arg2); ``` 注意:在声明中,您不能提供方法的实现。 2. 在C / C ++代码中实现新的本地方法,方法名称必须与您在Java中声明的方法名称一致。 ```cpp JNIEXPORT void JNICALL Java_com_example_MyClass_newMethod(JNIEnv *env, jobject obj, jint arg1, jstring arg2) { // 实现您的代码 } ``` 3. 最后,在您的C / C ++代码中获取Java类的引用,以便在Native代码中调用该方法。 ```cpp jclass clazz = env->FindClass("com/example/MyClass"); jmethodID methodId = env->GetMethodID(clazz, "newMethod", "(ILjava/lang/String;)V"); ``` 通过此方法ID,您可以使用JNI在C / C ++中调用该方法。 ```cpp env->CallVoidMethod(obj, methodId, arg1, arg2); ``` 这样,您就可以在Android 9.0和10.0的Framework系统API中添加新的JNI方法了。 ### 回答3: Android操作系统使用Java语言实现,但是也支持通过JNI机制(Java Native Interface)来调用C/C++编写的代码。在Android 9.0和10.0版本中,如果需要在Framework系统层中添加JNI方法,需要进行以下步骤: 1. 编写C/C++代码实现需要的功能,并将其编译成动态库(.so文件)。 2. 在Framework层中找到对应的Java类,并添加需要的Native方法声明。例如,如果要在TelephonyManager类中添加一个名为getSignalStrengthDbm的方法,则应该在TelephonyManager.java添加以下Native方法声明: ``` private native int getSignalStrengthDbm(); ``` 3. 在frameworks/base目录下的services/core/jni目录中添加一个名为TelephonyManager.cpp的文件,并实现getSignalStrengthDbm方法: ``` static jint TelephonyManager_getSignalStrengthDbm(JNIEnv *env, jobject thiz){ // TODO: 通过调用C/C++代码实现需要的功能,并返回结果 return 0; } static const JNINativeMethod gMethods[] = { { "getSignalStrengthDbm", "()I", (void*)TelephonyManager_getSignalStrengthDbm}, }; int register_android_telephony_TelephonyManager(JNIEnv* env) { jclass clazz = env->FindClass("android/telephony/TelephonyManager"); if (clazz == NULL) { ALOGE("Can't find android/telephony/TelephonyManager"); return -1; } return env->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(JNINativeMethod)); } ``` 4. 在frameworks/base目录下的services/core目录中找到文件Android.bp,将添加的TelephonyManager.cpp文件加入build文件中: ``` cc_library_shared { name: "libandroidfw", srcs: [ "jni/Animation.cpp", ... "jni/TelephonyManager.cpp", ], ... } ``` 5. 在Android.mk文件添加TelephonyManager.cpp的编译规则: ``` LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := TelephonyManager LOCAL_CFLAGS := -Werror LOCAL_SRC_FILES := TelephonyManager.cpp LOCAL_SHARED_LIBRARIES := libutils libcutils libbinder include $(BUILD_SHARED_LIBRARY) ``` 6. 重新编译Framework层并运行即可。 以上是在Android 9.0和10.0系统中添加JNI方法的步骤,其中涉及到的文件和目录可能有所不同,在实际开发中需要根据具体情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值