Home | History | Annotate | Download | only in lights
      1 /* Copyright (C) 2011 The Android Open Source Project
      2  *
      3  * Original code licensed under the Apache License, Version 2.0 (the "License");
      4  * you may not use this software except in compliance with the License.
      5  * You may obtain a copy of the License at
      6  *
      7  *   http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software
     10  * distributed under the License is distributed on an "AS IS" BASIS,
     11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12  * See the License for the specific language governing permissions and
     13  * limitations under the License.
     14  *
     15  * This implements a lights hardware library for the Android emulator.
     16  * the following code should be built as a shared library that will be
     17  * placed into /system/lib/hw/lights.goldfish.so
     18  *
     19  * It will be loaded by the code in hardware/libhardware/hardware.c
     20  * which is itself called from
     21  * ./frameworks/base/services/jni/com_android_server_HardwareService.cpp
     22  */
     23 
     24 #ifdef LOG_TAG
     25 #undef LOG_TAG
     26 #define LOG_TAG "Lights"
     27 #endif
     28 
     29 /* we connect with the emulator through the "hw-control" qemud service */
     30 #define  LIGHTS_SERVICE_NAME "hw-control"
     31 
     32 #include <cutils/log.h>
     33 #include <stdint.h>
     34 #include <string.h>
     35 #include <unistd.h>
     36 #include <errno.h>
     37 #include <fcntl.h>
     38 #include <pthread.h>
     39 #include <sys/ioctl.h>
     40 #include <sys/types.h>
     41 #include <hardware/lights.h>
     42 #include "qemud.h"
     43 
     44 /* Set to 1 to enable debug messages to the log */
     45 #define DEBUG 0
     46 #if DEBUG
     47 # define D(...) ALOGD(__VA_ARGS__)
     48 #else
     49 # define D(...) do{}while(0)
     50 #endif
     51 
     52 #define  E(...)  ALOGE(__VA_ARGS__)
     53 
     54 /* Get brightness(0~255) from state. */
     55 static int
     56 rgb_to_brightness( struct light_state_t const* state )
     57 {
     58     int color = state->color & 0x00ffffff;
     59     return ((77 * ((color >> 16) & 0x00ff))
     60             + (150 * ((color >> 8) & 0x00ff)) + (29 * (color & 0x00ff))) >> 8;
     61 }
     62 
     63 /* set backlight brightness by LIGHTS_SERVICE_NAME service. */
     64 static int
     65 set_light_backlight( struct light_device_t* dev, struct light_state_t const* state )
     66 {
     67     /* Get Lights service. */
     68     int  fd = qemud_channel_open( LIGHTS_SERVICE_NAME );
     69 
     70     if (fd < 0) {
     71         E( "%s: no qemud connection", __FUNCTION__ );
     72         return -1;
     73     }
     74 
     75     D( "%s: On/Off %d/%d flashMode %d brightnessMode %d"
     76        " RGB = 0x%08x", __func__,
     77        state->flashOnMS,
     78        state->flashOffMS,
     79        state->flashMode,
     80        state->brightnessMode,
     81        state->color );
     82 
     83     int brightness = rgb_to_brightness( state );
     84 
     85     char buffer[64];
     86     snprintf( buffer, sizeof(buffer), "power:light:brightness:lcd_backlight:%d", brightness );
     87     D( "%s: lcd_backlight command: %s", __FUNCTION__, buffer );
     88 
     89     /* send backlight command to perform the backlight setting. */
     90     if (qemud_channel_send( fd, buffer, -1 ) < 0) {
     91         E( "%s: could not query lcd_backlight: %s", __FUNCTION__, strerror(errno) );
     92         close( fd );
     93         return -1;
     94     }
     95 
     96     close( fd );
     97     return 0;
     98 }
     99 
    100 static int
    101 set_light_buttons( struct light_device_t* dev, struct light_state_t const* state )
    102 {
    103     /* @Waiting for later implementation. */
    104     D( "%s: Not implemented.", __FUNCTION__ );
    105 
    106     return 0;
    107 }
    108 
    109 static int
    110 set_light_battery( struct light_device_t* dev, struct light_state_t const* state )
    111 {
    112     /* @Waiting for later implementation. */
    113     D( "%s: Not implemented.", __FUNCTION__ );
    114 
    115     return 0;
    116 }
    117 
    118 static int
    119 set_light_keyboard( struct light_device_t* dev, struct light_state_t const* state )
    120 {
    121     /* @Waiting for later implementation. */
    122     D( "%s: Not implemented.", __FUNCTION__ );
    123 
    124     return 0;
    125 }
    126 
    127 static int
    128 set_light_notifications( struct light_device_t* dev, struct light_state_t const* state )
    129 {
    130     /* @Waiting for later implementation. */
    131     D( "%s: Not implemented.", __FUNCTION__ );
    132 
    133     return 0;
    134 }
    135 
    136 static int
    137 set_light_attention( struct light_device_t* dev, struct light_state_t const* state )
    138 {
    139     /* @Waiting for later implementation. */
    140     D( "%s: Not implemented.", __FUNCTION__ );
    141 
    142     return 0;
    143 }
    144 
    145 /** Close the lights device */
    146 static int
    147 close_lights( struct light_device_t *dev )
    148 {
    149     free( dev );
    150 
    151     return 0;
    152 }
    153 
    154 /**
    155  * module methods
    156  */
    157 
    158 /** Open a new instance of a lights device using name */
    159 static int
    160 open_lights( const struct hw_module_t* module, char const *name,
    161         struct hw_device_t **device )
    162 {
    163     void* set_light;
    164 
    165     if (0 == strcmp( LIGHT_ID_BACKLIGHT, name )) {
    166         set_light = set_light_backlight;
    167     } else if (0 == strcmp( LIGHT_ID_KEYBOARD, name )) {
    168         set_light = set_light_keyboard;
    169     } else if (0 == strcmp( LIGHT_ID_BUTTONS, name )) {
    170         set_light = set_light_buttons;
    171     } else if (0 == strcmp( LIGHT_ID_BATTERY, name )) {
    172         set_light = set_light_battery;
    173     } else if (0 == strcmp( LIGHT_ID_NOTIFICATIONS, name )) {
    174         set_light = set_light_notifications;
    175     } else if (0 == strcmp( LIGHT_ID_ATTENTION, name )) {
    176         set_light = set_light_attention;
    177     } else {
    178         D( "%s: %s light isn't supported yet.", __FUNCTION__, name );
    179         return -EINVAL;
    180     }
    181 
    182     struct light_device_t *dev = malloc( sizeof(struct light_device_t) );
    183     if (dev == NULL) {
    184         return -EINVAL;
    185     }
    186     memset( dev, 0, sizeof(*dev) );
    187 
    188     dev->common.tag = HARDWARE_DEVICE_TAG;
    189     dev->common.version = 0;
    190     dev->common.module = (struct hw_module_t*)module;
    191     dev->common.close = (int (*)(struct hw_device_t*))close_lights;
    192     dev->set_light = set_light;
    193 
    194     *device = (struct hw_device_t*)dev;
    195     return 0;
    196 }
    197 
    198 static struct hw_module_methods_t lights_module_methods = {
    199     .open =  open_lights,
    200 };
    201 
    202 /*
    203  * The emulator lights Module
    204  */
    205 struct hw_module_t HAL_MODULE_INFO_SYM = {
    206     .tag = HARDWARE_MODULE_TAG,
    207     .version_major = 1,
    208     .version_minor = 0,
    209     .id = LIGHTS_HARDWARE_MODULE_ID,
    210     .name = "Goldfish lights Module",
    211     .author = "The Android Open Source Project",
    212     .methods = &lights_module_methods,
    213 };
    214