MT6572平台加入呼吸灯功能——编写Framework层接口

    在Android中,硬件服务一般运行在一个独立进程中为各种应用程序提供服务,这就涉及到进程间通信。Android系统Java层面一般使用AIDL来定义进程间通信接口。

    AIDL是Android Interface Definition Language的缩写,即Android接口描述语言,用于约束进程间通信规则。如果在一个进程(Activity)中要调用另一个进程(Service)中对象的操作方法,就可以使用AIDL设计远程接口。AIDL IPC机制是面向接口的,它使用代理类在客户端和服务端传递数据。

    使用AIDL首先要创建一个.aidl文件,aidl文件内容与Java文件非常相似,但是不能加修饰符(public,private等)和AIDL服务不支持的数据类型(InputStream,OutputStream等)。编译时系统工具会根据aidl文件生成相应的.java文件即java接口类,生成的接口类中包含一个名为Stub的抽象内部类,该类中声明了所有aidl文件中描述的方法,Stub还定义了少量的辅助方法,特别是asInterface(),通过它可获得IBinder(Android的远程调用就是通过IBinder实现的)并且返回用于调用IPC方法的接口实例。要实现自己的接口,就要继承该Stub类。

    本实验中呼吸灯服务添加进了系统服务,下面记录下开发过程:

    1)创建AIDL接口文件

        进入frameworks/base/core/java/android/os/目录,新增IBreathLedsService.aidl文件:


 
 
  1. package android.os;
  2. /** @hide */
  3. interface IBreathLedsService {
  4. void turnOnLeds();
  5. void turnOffLeds();
  6. void setLedsBrightness(int which, int level);
  7. }
IBreathLedsService这里只提供了打开呼吸灯,关闭呼吸灯和调节呼吸灯亮度三个接口服务,其中setLedsBrightness方法的第一个参数which表示led灯号,最多可控12个灯,可赋值1~12,level表示亮度等级,公32级亮度,可赋值0~31。IBreathLedsService.aidl文件不是必须放在该目录下,放在其他目录也可以,只要在相应Android.mk中加入编译路径就行。

        另外注意,上面的/** @hide */必须要加,否则编译整个系统的时候会提示make update-api之类的错误。

    2)在Android.mk中添加编译路径

        打开frameworks/base/Android.mk文件,在LOCAL_SRC_FILES变量中加入:

core/java/android/os/IBreathLedsService.aidl \
编译后,系统会自动生成对应的IBreathLedsService.java接口类,其中包含IBreathLedsService.Stub内部接口类。

    3)新建java文件继承上述Stub接口,编写Framework接口的具体实现

        进入frameworks/base/services/java/com/android/server/目录,新增BreathLedsService.java:


 
 
  1. package com.android.server;
  2. import android.os.IBreathLedsService;
  3. public class BreathLedsService extends IBreathLedsService.Stub {
  4. //亮度等级(32级)
  5. private static final int[] BRIGHTNESS_LEVEL = {
  6. 0, 1, 2, 4, 6, 10, 13, 18,
  7. 22, 28, 33, 39, 46, 53, 61, 69,
  8. 78, 86, 96, 106, 116, 126, 138, 149,
  9. 161, 173, 186, 199, 212, 226, 240, 255,
  10. };
  11. BreathLedsService () {
  12. init_native();
  13. }
  14. public void turnOnLeds() {
  15. set_brightness_native( 0x80);
  16. }
  17. public void turnOffLeds() {
  18. set_brightness_native( 0x00);
  19. }
  20. public void setLedsBrightness(int which, int level) {
  21. if ((which > 12) || (which < 1)) return;
  22. level = level % 32;
  23. int data = (( 0x80 | which) << 8) | BRIGHTNESS_LEVEL[level];
  24. set_brightness_native(data);
  25. }
  26. private native void init_native();
  27. private native void set_brightness_native(int data);
  28. }
其中init_native()和set_brightness_native()方法的实体在jni层实现,具体实现见上篇“编写JNI”;BRIGHTNESS_LEVEL表示led等亮度等级,有32个等级,具体数值的由来见前面的“控制芯片SN3112-12简介 ”。

    4)将新服务添加进系统服务中去

        打开上述同目录下的SystemServer.java文件,在ServerThread::run()方法中添加加载代码:


 
 
  1. try {
  2. Slog.i(TAG, "BreathLeds Service");
  3. ServiceManager.addService( "breath_leds", new BreathLedsService());
  4. } catch (Throwable e) {
  5. Slog.e(TAG, "Failure starting BreathLeds Service", e);
  6. }
注意,要记住这个tag字符串"breath_leds",APP会通过该tag获取该服务。最后,编译即完成了本实验的所有开发,下一篇将以一个简单实例介绍下新添加功能的调用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值