这篇文章使用JNI访问上篇文章写的设备驱动设备!
1. 更改te文件权限,重新编译android, 将boot.img替换
2. 需要将/dev/myhello的权限设置为777
3. 使用android studio创建一个jni程序
cpp的内容如下:
运行,则可以看到打印timur, 打印timur2则说明说明权限有问题
1. 更改te文件权限,重新编译android, 将boot.img替换
在android5或5.1的开发中经常会碰到,明明设备节点是有777的权限,可是在我们程序中访问这个设备却报Permission denied,无法打开设备。
这是因为在Android 5.0或5.1下,采取了SEAndroid/SElinux的安全机制。
SELINUX是美国国家安全局和一些公司设计的一个针对linux的安全加强系统,在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。
下面我们来看看怎么设置来允许我们的应用可以访问设备节点。
第一步,我们找到file_contexts文件,这个文件通常在device/mypaltform/sepolicy 或者external/sepolicy目录下。我们在这个文件下增加一行 “/dev/devname u:object_r:my_device:s0”。/dev/devname是设备节点,也就是我们要打开的设备名。my_device我们可以定义一个我们看的懂的有意义的名字。object_r标明这是一个文件。s0是表示优先级的。
第二步,在device.te文件中添加一行 “type my_device, dev_type ”;
第三步,在对应的在device/mypaltform/sepolicy 或者external/sepolicy目录下找到进程名加te为扩展名的,例如如果我们希望rild程序可以访问我们的节点可以打开rild.te文件在后面加上一行“allow rild my_device:chr_file rw_file_perms;”这时我们重新编译后,再看看在rild进程里面打开/dev/devname,读写这个设备文件都正常了。可是在实际的开发中往往是我们并不知道这个驱动将会被哪个应用程序调用,可能其他人调用我们的驱动做开发,或者安装第三方APP。如果是这样,我们可以找到例如app.te、systemp_app.te、untrusted_app.te。等文件,在里面加上如“allow appdomain my_device:chr_file rw_file_perms; ”(表示所有的APP都可以访问该设备节点)、“allow system_app my_device:chr_file rw_file_perms; ”表示具有system UID的APP都可以访问该设备节点)、“allow untrusted_app my_device:chr_file rw_file_perms;”(表示所有第三方的APP都可以访问该设备节点)。或者直接打开domain.te加上“allow domain my_device:chr_file rw_file_perms;”(所有的进程、服务都可以访问该节点)。当然了,实际上上诉的语句不一定放在上面指定的文件里,放在任何文件里效果是一样的,但是为了方便阅读和管理,还是添加到对应的文件中比较好。
2. 需要将/dev/myhello的权限设置为777
3. 使用android studio创建一个jni程序
cpp的内容如下:
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_timur_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
int fd = open("/dev/myhello", O_RDWR);
std::string hello = "Hello timur";
if(fd<0) hello = "Hello timur2";
write(fd, "xxxxxx", 5);
close(fd);
return env->NewStringUTF(hello.c_str());
}
运行,则可以看到打印timur, 打印timur2则说明说明权限有问题
问题:chmod 777 /dev/myhello 这一步,如何用代码来实现?不知道!
2018.2.20