在上一篇中,我们已经搭建好了服务端的代码结构,并且保证编译通过;
但是由于各种坑的存在,我们无法直接让服务端跑起来,因此本篇不是写客户端调用,而是一篇和编译规则定义、selinux规则添加等相关的踩坑总集,如果你已经保证服务端已经跑起来了,那么本篇可以跳过,等下一篇吧;
添加编译规则在device///device.mk或等效的位置添加:
PRODUCT_PACKAGES += \
vendor.zsui.hardware.example@1.0 \
vendor.zsui.hardware.example@1.0-service
然后全编译userdebug版本,刷机;
添加SELinux规则开机以后会发现service并未启动,且报了如下权限拒绝:
01-29 19:27:59.819 0 0 E init : File /vendor/bin/hw/vendor.zsui.hardware.example@1.0-service(labeled "u:object_r:vendor_file:s0") has incorrect label or no domain transition from u:r:init:s0 to another SELinux domain defined. Have you configured your service correctly? https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials
01-29 19:27:59.819 0 0 I init : starting service 'example-hal-1-0'...
02-26 10:45:58.440 2978 2978 I auditd : type=1400 audit(0.0:127): avc: denied { execute } for comm="init" name="vendor.zsui.hardware.example@1.0-service" dev="mmcblk0p48" ino=515 scontext=u:r:init:s0 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0
01-29 19:27:59.822 0 0 E init : cannot execve('/vendor/bin/hw/vendor.zsui.hardware.example@1.0-service'): Permission denied
02-26 10:45:58.440 2978 2978 W init : type=1400 audit(0.0:127): avc: denied { execute } for name="vendor.zsui.hardware.example@1.0-service" dev="mmcblk0p48" ino=515 scontext=u:r:init:s0 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0
01-29 19:27:59.828 0 0 I init : Service 'example-hal-1-0' (pid 2978) exited with status 127
01-29 19:27:59.828 0 0 I init : Sending signal 9 to service 'example-hal-1-0' (pid 2978) process group...
显而易见的selinux权限问题,这里就直接提供全套了:
file_contexts:
/(system\/vendor|vendor)/bin/hw/vendor\.zsui\.hardware\.example@1\.0-service u:object_r:zsui_hal_exec:s0
hwservice_contexts:
vendor.zsui.hardware.example::IExample u:object_r:zsui_hal_hwservice:s0
hwservice.te
type zsui_hal_hwservice, hwservice_manager_type;
zsui_hal.te
type zsui_hal, domain;
type zsui_hal_exec, exec_type, file_type, vendor_file_type;
add_hwservice(zsui_hal, zsui_hal_hwservice)
init_daemon_domain(zsui_hal)
hwbinder_use(zsui_hal);
allow zsui_hal hwservicemanager_prop:file { read open getattr };
注:名字对应关系请自行修改;
编译刷机后如果不想回复出厂设置,但是始终无法识别新增的上下文标签,可以尝试使用强制刷新label:(需要remount)
adb shell restorecon -R /vendor/bin/hw/vendor.zsui.hardware.example@1.0-service
重启手机,然后通过ps指令查看,进程已经跑起来了:
$ adb shell ps -A | grep example
root 513 1 12596 2384 binder_thread_read 0 S vendor.zsui.hardware.example@1.0-service
坑踩得差不多了,这篇就到这里了。
下一篇会着重讲解JAVA侧调用的问题;
文笔有限,若有谬误,还请指出;
感谢!
作者:Ryan ZHENG