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 <hardware/qemud.h> 43 44 /* Set to 1 to enable debug messages to the log */ 45 #define DEBUG 0 46 #if DEBUG 47 # define D(...) LOGD(__VA_ARGS__) 48 #else 49 # define D(...) do{}while(0) 50 #endif 51 52 #define E(...) LOGE(__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 const 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