第一部分:编写hal服务
1.先全编译源码:
source build/envset.sh
lunch
make
2.安装hidl-gen工具:
make hidl-gen
3.在hardware/interfaces/automotive目录下新建mcuupdate/1.0目录,并在1.0目录中创建接口IMcuUpdate.hal。

4.执行下面命令会自动生成对应的C++文件:
hidl-gen -o hardware/interfaces/automotive/mcuupdate/1.0/default -Lc++-impl -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.automotive.mcuupdate@1.0
执行后会在1.0文件夹下新建default文件夹,此文件夹中会生成McuUpdate.h和McuUpdate.cpp文件;
5.执行下面命令,会在hardware/interfaces/automotive/mcuupdate/1.0/default目录中生成Android.bp文件:
hidl-gen -o hardware/interfaces/automotive/mcuupdate/1.0/default -Landroidbp-impl -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.automotive.mcuupdate@1.0
6.执行下面命令,来更新Makefile:
./hardware/interfaces/update-makefiles.sh
执行完之后会在hardware/interfaces/automotive/mcuupdate/1.0目录中生成Android.bp文件
7.在hardware/interfaces/automotive/mcuupdate/1.0/default目录下新建android.hardware.automotive.mcuupdate@1.0-service.rc,此为程序的入口函数,文件内容如下:

8.在hardware/interfaces/automotive/mcuupdate/1.0/default目录下新建service.cpp,里面添加入口main函数:

9.打开hardware/interfaces/automotive/mcuupdate/1.0/default/Android.bp,添加编译service.cpp成为可执行文件的代码:

10.编译生成hidl服务端跟客户端要用的各种库文件:


编译完生成下列文件:
out\target\product\spm8666p1_64_car\vendor\bin\hw\android.hardware.automotive.mcuupdate@1.0-service
out\target\product\spm8675p1_64_wifi\system\apex\com.android.vndk.current\lib\android.hardware.automotive.mcuupdate@1.0.so
out\target\product\spm8675p1_64_wifi\system\apex\com.android.vndk.current\lib64\android.hardware.automotive.mcuupdate@1.0.so
11.在device/mediatek/mt6873/manifest.xml文件中添加以下内容,不然客户端无法拿到服务端service:

12.device\mediatek\mt6873\device.mk在尾部添加:
PRODUCT_PACKAGES += android.hardware.automotive.mcuupdate@1.0-service
13.全编译时如果出现error: VNDK library list has been changed错误,解决办法是把out\target\product\spm8666p1_64_car\obj\PACKAGING\vndk_intermediates\libs.txt的内容对比到build\make\target\product\vndk\current.txt和build\make\target\product\vndk\28.txt
14.切记:如果hal文件变更了,重新生成h和cpp时会覆盖,所以每次更改hal前把default目录改下名字,等生成完了,再把老的代码手动移到新生成的文件里面。
第二部分:配置selinux,以便service能在rc里面启动
1.在device\mediatek\mt6873\sepolicy\basic\file_contexts尾部添加
/(vendor|system/vendor)/bin/hw/android\.hardware\.automotive\.mcuupdate@1\.0-service u:object_r:hal_mcuupdate_default_exec:s0
2.新建device\mediatek\mt6873\sepolicy\basic\hal_mcuupdate_default.te,内容如下:
type hal_mcuupdate_default, domain,bicvdomain;
hal_server_domain(hal_mcuupdate_default, hal_mcuupdate)
type hal_mcuupdate_default_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_mcuupdate_default)
hal_client_domain(platform_app, hal_mcuupdate)
hal_client_domain(priv_app, hal_mcuupdate)
hal_client_domain(system_app, hal_mcuupdate)
allow hal_mcuupdate_default sysfs_mcuupdate:file { rw_file_perms };
allow hal_mcuupdate_default unlabeled:dir { search getattr };
allow hal_mcuupdate_default spi_device:chr_file { rw_file_perms };
allow hal_mcuupdate_default self:capability { dac_read_search dac_override };
allow hal_mcuupdate_default mnt_user_file:dir { search rw_file_perms };
allow hal_mcuupdate_default mnt_user_file:lnk_file { r_file_perms };
allow hal_mcuupdate_default storage_file:file { rw_file_perms };
allow hal_mcuupdate_default fuse:file { rw_file_perms };
allow hal_mcuupdate_default fuse:dir { search rw_file_perms };
allow hal_mcuupdate_default fota_file:file { r_file_perms };
allow hal_mcuupdate_default fota_file:dir { search r_file_perms };
allow hal_mcuupdate_default vendor_shell_exec:file { execute_no_trans };
allow hal_mcuupdate_default dsp_device:chr_file { rw_file_perms };
allow hal_mcuupdate_default system_file:file { r_file_perms map execute execute_no_trans };
allow hal_mcuupdate_default audio_device:chr_file { rw_file_perms };
allow hal_mcuupdate_default audio_device:dir { search rw_file_perms };
allow hal_mcuupdate_default system_data_root_file:dir { search rw_file_perms add_name };
allow hal_mcuupdate_default system_data_root_file:file { rw_file_perms };
bicvdomain是自定义的安全域,用来配置不受某些selinux规则限制,比如在规则里-bicvdomain代表这个域不受此规则的限制。
安全域需在system\sepolicy\public\attributes中申明:attribute bicvdomain;同步在system\sepolicy\prebuilts\api\30.0\public\attributes中也要申明。
3.在device\mediatek\mt6873\sepolicy\basic\hwservice.te尾部添加:
type hal_mcuupdate_hwservice, hwservice_manager_type, protected_hwservice;
4.新建device\mediatek\mt6873\sepolicy\basic\hal_mcuupdate.te,内容如下:
#HwBinder IPC from client to server, and callbacks
hal_attribute(mcuupdate);
binder_call(hal_mcuupdate_client, hal_mcuupdate_server)
binder_call(hal_mcuupdate_server, hal_mcuupdate_client)
add_hwservice(hal_mcuupdate_server, hal_mcuupdate_hwservice)
allow hal_mcuupdate_client hal_mcuupdate_hwservice:hwservice_manager find;
5.在device\mediatek\mt6873\sepolicy\basic\hwservice_contexts中按字母顺序添加
android.hardware.automotive.mcuupdate::IMcuUpdate u:object_r:hal_mcuupdate_hwservice:s0
需要跨进程使用的都要加上
6.编译中间接口、库和service:
mmm hardware/interfaces/automotive/mcuupdate/1.0
因为修改了很多selinux相关的东西,所以最终需要整个android源码编译一次。烧录到机器,就可以看到service起来了

第三部分:与上层app建立连接
1.方式一:使用AndroidStudio编译apk
前面android源码编译完之后,将会在out\target\common\obj\JAVA_LIBRARIES\生成android.hardware.automotive.mcuupdate-V1.0-java_intermediates文件夹,拷贝里面的classes.jar到AndroidStudio工程的libs中,implementation files('libs/classes.jar')引入;
2.方式二:系统源码中编译apk
在APP工程的Android.mk中加入LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.automotive.mcuupdate-V1.0-java-static
3.源码进行一次编译,烧录进机器
4.IMcuUpdate service = IMcuUpdate.getService(); 获取到IMcuUpdate后就可以调用它里面的方法了。
第四部分:与HIDL Client建立连接
1.Client进程在LOCAL_SHARED_LIBRARIES中添加android.hardware.automotive.mcuupdate@1.0
2.在Client中添加#include <android/hardware/automotive/mcuupdate/1.0/IMcuUpdate.h>
然后在函数中使用sp<IMcuUpdate> pMcuUpdate = IMcuUpdate::getService();即可绑定上服务。
网友评论