@ -46,12 +46,22 @@ char const*const BUTTON_FILE
= " /sys/class/sec/sec_touchkey/brightness " ;
# endif
# ifdef LED_NOTIFICATION
static char const RED_LED_DIR [ ] = " /sys/class/leds/red " ;
static char const BLUE_LED_DIR [ ] = " /sys/class/leds/blue " ;
# endif // LED_NOTIFICATION
void init_globals ( void )
{
// init the mutex
pthread_mutex_init ( & g_lock , NULL ) ;
}
# ifdef LED_NOTIFICATION
static struct led_state {
unsigned int enabled ;
int delay_on , delay_off ;
} battery_red , battery_blue , notifications_red , notifications_blue ;
# endif // LED_NOTIFICATION
static int
write_int ( char const * path , int value )
{
@ -74,6 +84,45 @@ write_int(char const* path, int value)
}
}
# ifdef LED_NOTIFICATION
static int write_str ( char const * path , char const * str )
{
int fd ;
static int already_warned = 0 ;
ALOGV ( " write_str: path= \" %s \" , str= \" %s \" . " , path , str ) ;
fd = open ( path , O_RDWR ) ;
if ( fd > = 0 ) {
int amt = write ( fd , str , strlen ( str ) ) ;
close ( fd ) ;
return amt = = - 1 ? - errno : 0 ;
} else {
if ( already_warned = = 0 ) {
ALOGE ( " write_str failed to open %s \n " , path ) ;
already_warned = 1 ;
}
return - errno ;
}
}
/* Should check for snprintf truncation, but as these functions only use
* internal paths , meh . */
static int write_df_int ( char const * dir , char const * file , int value )
{
char path [ PATH_MAX ] ;
snprintf ( path , sizeof ( path ) , " %s/%s " , dir , file ) ;
return write_int ( path , value ) ;
}
static int write_df_str ( char const * dir , char const * file , char const * str )
{
char path [ PATH_MAX ] ;
snprintf ( path , sizeof ( path ) , " %s/%s " , dir , file ) ;
return write_str ( path , str ) ;
}
# endif // LED_NOTIFICATION
static int
is_lit ( struct light_state_t const * state )
{
@ -88,6 +137,75 @@ rgb_to_brightness(struct light_state_t const* state)
+ ( 150 * ( ( color > > 8 ) & 0x00ff ) ) + ( 29 * ( color & 0x00ff ) ) ) > > 8 ;
}
# ifdef LED_NOTIFICATION
static void comp_led_states ( struct led_state * red , struct led_state * blue ,
struct light_state_t const * state )
{
unsigned int color = state - > color ;
int delay_on , delay_off ;
switch ( state - > flashMode ) {
case LIGHT_FLASH_TIMED :
delay_on = state - > flashOnMS ;
delay_off = state - > flashOffMS ;
break ;
default :
ALOGI ( " Unsuported flashMode %d, default to NONE. " , state - > flashMode ) ;
case LIGHT_FLASH_NONE :
delay_on = delay_off = 0 ;
break ;
}
red - > enabled = ! ! ( color > > 16 & 0xff ) ;
red - > delay_on = delay_on ;
red - > delay_off = delay_off ;
blue - > enabled = ! ! ( color & 0xff ) ;
blue - > delay_on = delay_on ;
blue - > delay_off = delay_off ;
ALOGV ( " comp_led_states: red=(%u, %d, %d), blue=(%u, %d, %d). " ,
red - > enabled , red - > delay_on , red - > delay_off , blue - > enabled ,
blue - > delay_on , blue - > delay_off ) ;
}
static int set_led ( char const * dir , struct led_state const * battery ,
struct led_state const * notifications )
{
struct led_state const * state = NULL ;
int res ;
if ( notifications - > enabled )
state = notifications ;
else if ( battery - > enabled )
state = battery ;
if ( state ! = NULL ) {
int delay_on = state - > delay_on ;
int delay_off = state - > delay_off ;
if ( delay_on > 0 & & delay_off > 0 ) {
/* Handling of blink_count is wrong in the kernel, blinking indefinitely
* for any non - zero value . TW lights just sets it to 1. */
if ( ( res = write_df_str ( dir , " trigger " , " notification " ) ) < 0 ) return res ;
if ( ( res = write_df_str ( dir , " brightness " , " 255 " ) ) < 0 ) return res ;
if ( ( res = write_df_str ( dir , " blink_count " , " 1 " ) ) < 0 ) return res ;
if ( ( res = write_df_int ( dir , " delay_on " , delay_on ) ) < 0 ) return res ;
if ( ( res = write_df_int ( dir , " delay_off " , delay_off ) ) < 0 ) return res ;
} else {
if ( ( res = write_df_str ( dir , " trigger " , " none " ) ) < 0 ) return res ;
if ( ( res = write_df_str ( dir , " brightness " , " 255 " ) ) < 0 ) return res ;
}
} else {
if ( ( res = write_df_str ( dir , " trigger " , " none " ) ) < 0 ) return res ;
if ( ( res = write_df_str ( dir , " brightness " , " 0 " ) ) < 0 ) return res ;
}
return 0 ;
}
# endif // LED_NOTIFICATION
static int
set_light_backlight ( struct light_device_t * dev ,
struct light_state_t const * state )
@ -126,14 +244,46 @@ static int
set_light_battery ( struct light_device_t * dev ,
struct light_state_t const * state )
{
return 0 ;
int res = 0 ;
# ifdef LED_NOTIFICATION
ALOGD ( " set_light_battery: color=%#010x, fM=%u, fOnMS=%d, fOffMs=%d. " ,
state - > color , state - > flashMode , state - > flashOnMS , state - > flashOffMS ) ;
pthread_mutex_lock ( & g_lock ) ;
comp_led_states ( & battery_red , & battery_blue , state ) ;
if ( ( res = set_led ( RED_LED_DIR , & battery_red , & notifications_red ) ) > = 0 )
res = set_led ( BLUE_LED_DIR , & battery_blue , & notifications_blue ) ;
pthread_mutex_unlock ( & g_lock ) ;
# endif // LED_NOTIFICATION
return res ;
}
static int
set_light_notification ( struct light_device_t * dev ,
struct light_state_t const * state )
{
return 0 ;
int res = 0 ;
# ifdef LED_NOTIFICATION
ALOGD ( " set_light_notification: color=%#010x, fM=%u, fOnMS=%d, fOffMs=%d. " ,
state - > color , state - > flashMode , state - > flashOnMS , state - > flashOffMS ) ;
pthread_mutex_lock ( & g_lock ) ;
comp_led_states ( & notifications_red , & notifications_blue , state ) ;
if ( ( res = set_led ( RED_LED_DIR , & battery_red , & notifications_red ) ) > = 0 )
res = set_led ( BLUE_LED_DIR , & battery_blue , & notifications_blue ) ;
pthread_mutex_unlock ( & g_lock ) ;
# endif // LED_NOTIFICATION
return res ;
}
static int