[小制作]手机震动坏了,重新实现震动为闪烁LED


最近手里的xt897 震动坏了。

正好重温一下Android的Service机制和Hal实现,把震动变为LED闪烁。

11月19日:

首先找到震动打调用方法:

vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);   
long[] pattern = {800, 50, 400, 30}; // OFF/ON/OFF/ON...   
vibrator.vibrate(pattern, 2);

VibratorService.java 在 frameworks/base/services/java/com/android/server/VibratorService.java


里面是关于震动调用打一些业务逻辑

最终会调用到

    native static boolean vibratorExists();
    native static void vibratorOn(long milliseconds);
    native static void vibratorOff();


因为最后只是为了适配我的手机。所以怎么方便怎么改来。

如果修改VibratorService.java 要编译Android系统 显然比较麻烦。

修改native只需要编译内核。

------------JNI层----------------------------

对应的native函数在

android/frameworks/base/services/jni/

com_android_server_VibratorService.cpp

查看Android.mk  ,这个需要学习一下Android.mk语法

这里的文件最终会生成libandroid_servers.so

jni层的vibratorOff 实现:

static void vibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms)
{
    // LOGI("vibratorOn\n");
    vibrator_on(timeout_ms);
}

vibrator_on 是Hal层的函数

-----------Hal层------------------------

目录:$A10_ANDROID_SRC_PATH/hardware/lighardware_legacy/

<vibrator/Android.mk>:

# Copyright 2006 The Android Open Source Project

LOCAL_SRC_FILES += vibrator/vibrator.c


<Android.mk>:

#这个文件有好几个Local_module 不过这个才是我们关心的

LOCAL_MODULE:= libhardware_legacy

输出:

ls /disk1/sources/cyanogenmod/source_cm11/out/target/product/xt897/system/lib/libhardware_legacy.so

实现:

static int sendit(int timeout_ms)
{
    int nwr, ret, fd;
    char value[20];

#ifdef QEMU_HARDWARE
    if (qemu_check()) {
        return qemu_control_command( "vibrator:%d", timeout_ms );
    }
#endif

    fd = open(THE_DEVICE, O_RDWR);
    if(fd < 0)
        return errno;

    nwr = sprintf(value, "%d\n", timeout_ms);
    ret = write(fd, value, nwr);

    close(fd);

    return (ret == nwr) ? 0 : -1;
}

int vibrator_on(int timeout_ms)
{
    /* constant on, up to maximum allowed time */
    return sendit(timeout_ms);
}

THE_DEVICE 即 


#define THE_DEVICE "/sys/class/timed_output/sun4i-vibrator/enable"



想要在Hal层修改为闪烁LED 还得看LED的实现:

jni:

com_android_server_LightsService.cpp

msm8960 lights hal :

/disk1/sources/cyanogenmod/source_cm11/hardware/qcom/display/msm8960/liblight/

lights.c

不用看实现函数,看开头的几个宏就知道怎么回事了:

char const*const RED_LED_FILE
        = "/sys/class/leds/red/brightness";

char const*const GREEN_LED_FILE
        = "/sys/class/leds/green/brightness";

char const*const BLUE_LED_FILE
        = "/sys/class/leds/blue/brightness";

char const*const WHITE_LED_FILE
        = "/sys/class/leds/white/brightness";

char const*const LCD_FILE
        = "/sys/class/leds/lcd-backlight/brightness";

char const*const LED_FREQ_FILE
        = "/sys/class/leds/%s/device/grpfreq";

char const*const LED_PWM_FILE
        = "/sys/class/leds/%s/device/grppwm";

char const*const LED_BLINK_FILE
        = "/sys/class/leds/%s/device/blink";

char const*const LED_LOCK_UPDATE_FILE
        = "/sys/class/leds/%s/device/lock";

搜一下RED_LED_FILE

    if (rgb) {
        write_int(RED_LED_FILE, (colorRGB >> 16) & 0xFF);
        write_int(GREEN_LED_FILE, (colorRGB >> 8) & 0xFF);
        write_int(BLUE_LED_FILE, colorRGB & 0xFF);
    }

使用adb shell

echo 255 > /sys/class/leds/red/brightness

确实能亮。

那就直接回到vibrator.c 改吧:

添加 :

char const*const RED_LED_FILE
        = "/sys/class/leds/red/brightness";

char const*const GREEN_LED_FILE
        = "/sys/class/leds/green/brightness";

char const*const BLUE_LED_FILE
        = "/sys/class/leds/blue/brightness";

char const*const BLINK_VALUE = "255";

static int write_max(int fd)
{
    int ret = write(fd,BLINK_VALUE,strlen(BLINK_VALUE));
    return ret;
}

static int lights_reset(int fdr,int fd_g,int fd_b){
    int ret;
    ret = write(fdr,"0",strlen("0"));
    ret = write(fd_g,"0",strlen("0"));
    ret = write(fd_b,"0",strlen("0"));
    return ret;
}
#define INTERVAL 200
static int sendit(int timeout_ms){
    int fd_r,fd_g,fd_b,ret,i,cur_time_ms = 0,mod,div;
    fd_r = open(RED_LED_FILE,O_RDWR);
    fd_g = open(GREEN_LED_FILE,O_RDWR);
    fd_b = open(BLUE_LED_FILE,O_RDWR);
    ret = fd_r<0?-1:(fd_g<0?-1:fd_b<0?-1:0);
    if((fd_r<0)||(fd_g<0)||(fd_b<0))
        return -1;
    if(timeout_ms < INTERVAL){
        write_max(fd_r);
        write_max(fd_g);
        write_max(fd_b);
        for(i=0;i<timeout_ms;i++)
            usleep(1000);
        lights_reset(fd_r,fd_g,fd_b);
        printf("!!!!timeout_ms is %d\n",timeout_ms);
        return 0;
    }
        
    while(cur_time_ms<timeout_ms){

        if(cur_time_ms%INTERVAL==0)
        {// call once in INTERVAL ms;
            div = cur_time_ms/INTERVAL;
            mod = div%3;
            lights_reset(fd_r,fd_g,fd_b);
            if(mod==0)
                write_max(fd_r);
            else if(mod == 1)
                write_max(fd_g);
            else if(mod==2)
                write_max(fd_b);
        }
        usleep(1000);
        cur_time_ms++;
    }
    return 0;
}

然后

source build/envsetup.sh

breakfast xt897

cd /disk1/sources/cyanogenmod/source_cm11/hardware/libhardware_legacy

mm


[root@ libhardware_legacy]# adb push /disk1/sources/cyanogenmod/source_cm11/out/target/product/xt897/obj/lib/libhardware_legacy.so /sdcard/
[root@ libhardware_legacy]# adb shell
shell@asanti_c:/ $ su   
root@asanti_c:/ # cat /sdcard/remount.sh 2>&0|sh                               
root@asanti_c:/ # cp /sdcard/lib
libhardware_legacy.so     libs/                     
root@asanti_c:/ # cp /sdcard/libhardware_legacy.so /system/lib


即可.

威信设置的震动时间200ms,所以小于200ms的干脆让它常亮得了。

done









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值