当系统中缺少某个特定版本的 libc 的时候,可以在编译的时候,添加 -nostdlib 选项,并在后面附上指定的库即可。类似于
arm-linux-gcc -fPIC -shared hardcontrol.c -o libhardcontrol.so -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -nostdlib /work/android-5.0.2/prebuilts/ndk/9/platform/android-19/arch-arm/usr/lib/libc.so
当c文件编译的时候,找不到 log 方面的头文件和库的时候,可以手动添加,类似下面这样
arm-linux-gcc -fPIC -shared hardcontrol.c -o libhardcontrol.so -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -nostdlib /work/android-5.0.2/prebuilts/ndk/9/platform/android-19/arch-arm/usr/lib/libc.so -I /work/android-5.0.2/prebuilts/ndk/9/platform/android-19/arch-arm/usr/include /work/android-5.0.2/prebuilts/ndk/9/platform/android-19/arch-arm/usr/lib/liblog.so
硬件服务中,xxx_service.cpp, hal_xxx.c 的关系
如 com_android_server_LedService.cpp 这样的文件是 jni 源码,主要做的是向系统注册的事情。hal_led.c 这样的是实际的对硬件进行操作的源码,比如说 read, write, ioctrl 等等。
之所以分开来主要考虑两个原因。
com_android_server_LedService.cpp这样的文件如果有变更,那么需要系统重新编译。hal_led.c这样的正常时编译为 so 库,所以可以不用系统重新编译。- 有些厂商为了保密的需要,不提供
hal_led.c这样的源码,只是提供一个 so 的库文件。 onload.cpp调用com_android_server_LedService.cpp中实现的函数SystemServer.java需要new LedService然后再addServiceLedService.java里面调用 native 方法ILedService.java给 app 来使用。
ILedService.java
- 仿照其他的 aidl 文件,比如说 vibr 的 aidl 文件,复制为
ILedService.aidl,然后修改一下接口。 - 查看 vibr aidl 文件所在的目录,放到类似的目录
- 从当前目录开始查看有没有
Android.mk,如果没有,就向上一层继续查找,知道找到为止。 - 在
Android.mk中仿照 vibr aidl,把ILedService.aidl加入进去。 - 使用
mmm .进行编译。 - 到 out 目录下找找有没有
ILedService.java生成 - 可以估计 app 中对 led 的用法是
ILedService iLedService; iLedService = ILedService.stub.asInterface(ServiceManager.getService("led")); iLedService.ledCtrl(0, 1);
参考 VibratorService.java 来写 LedService.java.
- LedService 继承了 ILedService.Stub, 到
ILedService.java找Stub申明实现的接口android.os.ILedService,android.os.ILedService这个里面自动生成的需要实现的只有ledCtrl这个函数。 - 在
LedService.java中实现ledCtrl,这个函数中直接调用 native 方法即可。别忘了申明 native 方法 - 在
LedService.java中的构造函数中也需要调用 open 的 native 方法。别忘了申明 native 方法 - 在
SystemServer.java中,找到 vibr 使用ServiceManager.addService的地方,仿照写个 led 的添加服务的调用。
com_android_server_LedService.cpp
参考 com_android_server_VibratorService.cpp 来写。
Onload.cpp
找到 register_android_server_VibratorService(env) 这个注册的地方,复制一份,改为 register_android_server_LedService(env). 别忘了添加这个函数相应的申明。
保存 mmm 编译时的指令
mmm frameworks/base show commands >log.txt 2>&1
在 app 中直接 import android.os.ILedService 会找不到
- 可以参考: https://stackoverflow.com/questions/7888191/how-do-i-build-the-android-sdk-with-hidden-and-internal-apis-available ,把
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar这个复制出来,并改个名字。 - 可以参考 https://stackoverflow.com/questions/16608135/android-studio-add-jar-as-library 中的在 android studio 中添加 jar 文件。
led_hal.c
参考 hardware/libhardware/modules/vibrator/vibrator.c 和 hardware.h 来写 led_hal.c
编译
上面这些修改好了之后,可以使用命令进行编译。
mmm frameworks/base/services
mmm hardware/libhardware/modules/led
make snod
logcat
logcat 在命令行中可以使用类似 logcat LedHal:I *:S 这样的方法来进行过滤。