展讯android LEDS模块分析----一个bug

来源:互联网 发布:js 标签添加属性 编辑:程序博客网 时间:2024/06/02 06:31
        话说当年我还是懵懂的少年,就被人告知,Linux一切皆文件。可这句话充其量如毛主席说的“好好学习,天天向上”一样,仅当作真理供奉。
        直到前两天,FC找我,让我看一个bug,说关机闹铃到了以后选择继续睡觉后屏灭掉了,但是键盘的灯不会灭下去。塞班到android虽然是人类进步的一小步,却是关机闹钟退化的一大步!这里不想bb太多关于关机闹钟的问题,不过倒是雷布斯当年把关机闹钟放到M2的他认为碉堡了的功能里面会让我唏嘘不已!
        好吧,闲话说得再多bug也不会自己解,莎士比亚说:解铃还需系铃人。从代码中来,就让代码来解决吧。先找到点击继续睡眠的函数地方,在external文件夹下面有一个sprd的目录,说明这是展讯给android定制的。找到闹钟alarm/alarm.c文件,定位到判断屏幕点击的函数,竟然有main()。多少年前谭老爷子教会我们写main和printf,但是现在貌似没怎么用到过,今日看到不甚亲切啊!main函数太大了,不想贴,截一点吧!

while(gs_boot_state.power_key_event == BOOT_STATE_NONE)                                //唤醒后就不停的判断
{
//left button
if(g_alarm_button_event == ALARM_BUTTON_EVENT_LEFT)                     //如果按下了左键,继续睡
{
//sleep
if(gs_boot_state.alarm_state == BOOT_ALARM_ALARMING)
{
musicProcess(g_alarm_ring_path,0);
update_delay_time(alarm_item_bak);
if(get_latest_alarm_time(&fire_alarm) > (g_alarm_snooze_time))
{
set_state(LCD_BRIGHTNESS_OFF);                                    //设置屏的状态为OFF
                                。。。
}
}
usleep(500000);
g_alarm_button_event = BOOT_STATE_NONE;
}
else if( g_alarm_button_event == ALARM_BUTTON_EVENT_MID)
{
                        。。。
              }
                。。。


        打蛇打七寸,世界程序千千万,我们这等凡夫俗子怎们能看得完,在茫茫程序中找到你想要的才是最明智的,就像世间美女万万千,屌丝们还是早日下手,美女常有,而适合你的不是每天都能看到的奥!这里很明显,肯定是set_state(LCD_BRIGHTNESS_OFF); 函数把我们的屏给熄掉了,稍微有点智商的人也应该想到,我们照着熄屏的函数仿造一个熄灭LED的函数不得了么。做不了苹果,三星也不错。跟进去

int  set_state(char *state)
{
int fd;
char *plight = NULL;
if(strcmp(state,LCD_BRIGHTNESS_ON) == 0)
{
plight = g_brightness;
g_sleep = 0;
}
else if(strcmp(state,LCD_BRIGHTNESS_OFF) == 0)
{
plight = "0";
g_sleep = 1;
}
fd = open(LCD_BACKLIGHT_BRIGHTNESS_PATH,O_RDWR|O_TRUNC);
if(fd < 0)
{
ERROR("can't set  brightness\n");
return -1;
}
LOGD("set backlight to %s\n", plight);
if(write(fd, plight, strlen(plight)) < 0)
{
ERROR("write brightness failed\n");
close(fd);
return -1;
}
close(fd);
return 0;
}

代码不多,就都贴了出来。应该不用多解释吧,那就把我们自己当作处理器,大脑走一遭。在判断出来 else if(strcmp(state,LCD_BRIGHTNESS_OFF) == 0)后plight = "0";那么,fd = open(LCD_BACKLIGHT_BRIGHTNESS_PATH,O_RDWR|O_TRUNC); 用si跟踪出来
#define LCD_BACKLIGHT_BRIGHTNESS_PATH  "/sys/class/leds/lcd-backlight/brightness"
打开这个目录后,if(write(fd, plight, strlen(plight)) < 0),再将为0的plight写入到这个节点,这样来实现屏灭。大功告成!凭借着男人的直觉,肯定还有一个目录为/sys/class/leds/keyboard-backlight/brightness,先不急写代码,实现一下吧。

邓爷爷说:实践是检验真理的唯一标准。带着这种信念,我把手机插上电脑,adb shell连接上去,果然,有
/sys/class/leds/keyboard-backlight/brightness这个东东,继续验证一下
#cat brightness
0
现在是LED灭的状态
#echo >brightness 100
见证奇迹的时刻,LED亮了,这种激动忽然让我想起来从不关心房价的年代的我用51单片机点亮了第一个led灯的情景。剩下的事情就变得简单了,我们只要仿照着lcd的做法,也对led操作一遍就够了。bug解决了!