18a94683196406b83b14218d1beef66067f126a16keunyoung/* Copyright (C) 2011 The Android Open Source Project 28a94683196406b83b14218d1beef66067f126a16keunyoung * 38a94683196406b83b14218d1beef66067f126a16keunyoung * Original code licensed under the Apache License, Version 2.0 (the "License"); 48a94683196406b83b14218d1beef66067f126a16keunyoung * you may not use this software except in compliance with the License. 58a94683196406b83b14218d1beef66067f126a16keunyoung * You may obtain a copy of the License at 68a94683196406b83b14218d1beef66067f126a16keunyoung * 78a94683196406b83b14218d1beef66067f126a16keunyoung * http://www.apache.org/licenses/LICENSE-2.0 88a94683196406b83b14218d1beef66067f126a16keunyoung * 98a94683196406b83b14218d1beef66067f126a16keunyoung * Unless required by applicable law or agreed to in writing, software 108a94683196406b83b14218d1beef66067f126a16keunyoung * distributed under the License is distributed on an "AS IS" BASIS, 118a94683196406b83b14218d1beef66067f126a16keunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128a94683196406b83b14218d1beef66067f126a16keunyoung * See the License for the specific language governing permissions and 138a94683196406b83b14218d1beef66067f126a16keunyoung * limitations under the License. 148a94683196406b83b14218d1beef66067f126a16keunyoung * 158a94683196406b83b14218d1beef66067f126a16keunyoung * This implements a lights hardware library for the Android emulator. 168a94683196406b83b14218d1beef66067f126a16keunyoung * the following code should be built as a shared library that will be 178a94683196406b83b14218d1beef66067f126a16keunyoung * placed into /system/lib/hw/lights.goldfish.so 188a94683196406b83b14218d1beef66067f126a16keunyoung * 198a94683196406b83b14218d1beef66067f126a16keunyoung * It will be loaded by the code in hardware/libhardware/hardware.c 208a94683196406b83b14218d1beef66067f126a16keunyoung * which is itself called from 218a94683196406b83b14218d1beef66067f126a16keunyoung * ./frameworks/base/services/jni/com_android_server_HardwareService.cpp 228a94683196406b83b14218d1beef66067f126a16keunyoung */ 238a94683196406b83b14218d1beef66067f126a16keunyoung 248a94683196406b83b14218d1beef66067f126a16keunyoung#ifdef LOG_TAG 258a94683196406b83b14218d1beef66067f126a16keunyoung#undef LOG_TAG 268a94683196406b83b14218d1beef66067f126a16keunyoung#define LOG_TAG "Lights" 278a94683196406b83b14218d1beef66067f126a16keunyoung#endif 288a94683196406b83b14218d1beef66067f126a16keunyoung 298a94683196406b83b14218d1beef66067f126a16keunyoung/* we connect with the emulator through the "hw-control" qemud service */ 308a94683196406b83b14218d1beef66067f126a16keunyoung#define LIGHTS_SERVICE_NAME "hw-control" 318a94683196406b83b14218d1beef66067f126a16keunyoung 328a94683196406b83b14218d1beef66067f126a16keunyoung#include <cutils/log.h> 338a94683196406b83b14218d1beef66067f126a16keunyoung#include <stdint.h> 348a94683196406b83b14218d1beef66067f126a16keunyoung#include <string.h> 358a94683196406b83b14218d1beef66067f126a16keunyoung#include <unistd.h> 368a94683196406b83b14218d1beef66067f126a16keunyoung#include <errno.h> 378a94683196406b83b14218d1beef66067f126a16keunyoung#include <fcntl.h> 388a94683196406b83b14218d1beef66067f126a16keunyoung#include <pthread.h> 398a94683196406b83b14218d1beef66067f126a16keunyoung#include <sys/ioctl.h> 408a94683196406b83b14218d1beef66067f126a16keunyoung#include <sys/types.h> 418a94683196406b83b14218d1beef66067f126a16keunyoung#include <hardware/lights.h> 428a94683196406b83b14218d1beef66067f126a16keunyoung#include <hardware/qemud.h> 438a94683196406b83b14218d1beef66067f126a16keunyoung 448a94683196406b83b14218d1beef66067f126a16keunyoung/* Set to 1 to enable debug messages to the log */ 458a94683196406b83b14218d1beef66067f126a16keunyoung#define DEBUG 0 468a94683196406b83b14218d1beef66067f126a16keunyoung#if DEBUG 478a94683196406b83b14218d1beef66067f126a16keunyoung# define D(...) ALOGD(__VA_ARGS__) 488a94683196406b83b14218d1beef66067f126a16keunyoung#else 498a94683196406b83b14218d1beef66067f126a16keunyoung# define D(...) do{}while(0) 508a94683196406b83b14218d1beef66067f126a16keunyoung#endif 518a94683196406b83b14218d1beef66067f126a16keunyoung 528a94683196406b83b14218d1beef66067f126a16keunyoung#define E(...) ALOGE(__VA_ARGS__) 538a94683196406b83b14218d1beef66067f126a16keunyoung 548a94683196406b83b14218d1beef66067f126a16keunyoung/* Get brightness(0~255) from state. */ 558a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 568a94683196406b83b14218d1beef66067f126a16keunyoungrgb_to_brightness( struct light_state_t const* state ) 578a94683196406b83b14218d1beef66067f126a16keunyoung{ 588a94683196406b83b14218d1beef66067f126a16keunyoung int color = state->color & 0x00ffffff; 598a94683196406b83b14218d1beef66067f126a16keunyoung return ((77 * ((color >> 16) & 0x00ff)) 608a94683196406b83b14218d1beef66067f126a16keunyoung + (150 * ((color >> 8) & 0x00ff)) + (29 * (color & 0x00ff))) >> 8; 618a94683196406b83b14218d1beef66067f126a16keunyoung} 628a94683196406b83b14218d1beef66067f126a16keunyoung 638a94683196406b83b14218d1beef66067f126a16keunyoung/* set backlight brightness by LIGHTS_SERVICE_NAME service. */ 648a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 658a94683196406b83b14218d1beef66067f126a16keunyoungset_light_backlight( struct light_device_t* dev, struct light_state_t const* state ) 668a94683196406b83b14218d1beef66067f126a16keunyoung{ 678a94683196406b83b14218d1beef66067f126a16keunyoung /* Get Lights service. */ 688a94683196406b83b14218d1beef66067f126a16keunyoung int fd = qemud_channel_open( LIGHTS_SERVICE_NAME ); 698a94683196406b83b14218d1beef66067f126a16keunyoung 708a94683196406b83b14218d1beef66067f126a16keunyoung if (fd < 0) { 718a94683196406b83b14218d1beef66067f126a16keunyoung E( "%s: no qemud connection", __FUNCTION__ ); 728a94683196406b83b14218d1beef66067f126a16keunyoung return -1; 738a94683196406b83b14218d1beef66067f126a16keunyoung } 748a94683196406b83b14218d1beef66067f126a16keunyoung 758a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: On/Off %d/%d flashMode %d brightnessMode %d" 768a94683196406b83b14218d1beef66067f126a16keunyoung " RGB = 0x%08x", __func__, 778a94683196406b83b14218d1beef66067f126a16keunyoung state->flashOnMS, 788a94683196406b83b14218d1beef66067f126a16keunyoung state->flashOffMS, 798a94683196406b83b14218d1beef66067f126a16keunyoung state->flashMode, 808a94683196406b83b14218d1beef66067f126a16keunyoung state->brightnessMode, 818a94683196406b83b14218d1beef66067f126a16keunyoung state->color ); 828a94683196406b83b14218d1beef66067f126a16keunyoung 838a94683196406b83b14218d1beef66067f126a16keunyoung int brightness = rgb_to_brightness( state ); 848a94683196406b83b14218d1beef66067f126a16keunyoung 858a94683196406b83b14218d1beef66067f126a16keunyoung char buffer[64]; 868a94683196406b83b14218d1beef66067f126a16keunyoung snprintf( buffer, sizeof(buffer), "power:light:brightness:lcd_backlight:%d", brightness ); 878a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: lcd_backlight command: %s", __FUNCTION__, buffer ); 888a94683196406b83b14218d1beef66067f126a16keunyoung 898a94683196406b83b14218d1beef66067f126a16keunyoung /* send backlight command to perform the backlight setting. */ 908a94683196406b83b14218d1beef66067f126a16keunyoung if (qemud_channel_send( fd, buffer, -1 ) < 0) { 918a94683196406b83b14218d1beef66067f126a16keunyoung E( "%s: could not query lcd_backlight: %s", __FUNCTION__, strerror(errno) ); 928a94683196406b83b14218d1beef66067f126a16keunyoung close( fd ); 938a94683196406b83b14218d1beef66067f126a16keunyoung return -1; 948a94683196406b83b14218d1beef66067f126a16keunyoung } 958a94683196406b83b14218d1beef66067f126a16keunyoung 968a94683196406b83b14218d1beef66067f126a16keunyoung close( fd ); 978a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 988a94683196406b83b14218d1beef66067f126a16keunyoung} 998a94683196406b83b14218d1beef66067f126a16keunyoung 1008a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 1018a94683196406b83b14218d1beef66067f126a16keunyoungset_light_buttons( struct light_device_t* dev, struct light_state_t const* state ) 1028a94683196406b83b14218d1beef66067f126a16keunyoung{ 1038a94683196406b83b14218d1beef66067f126a16keunyoung /* @Waiting for later implementation. */ 1048a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: Not implemented.", __FUNCTION__ ); 1058a94683196406b83b14218d1beef66067f126a16keunyoung 1068a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 1078a94683196406b83b14218d1beef66067f126a16keunyoung} 1088a94683196406b83b14218d1beef66067f126a16keunyoung 1098a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 1108a94683196406b83b14218d1beef66067f126a16keunyoungset_light_battery( struct light_device_t* dev, struct light_state_t const* state ) 1118a94683196406b83b14218d1beef66067f126a16keunyoung{ 1128a94683196406b83b14218d1beef66067f126a16keunyoung /* @Waiting for later implementation. */ 1138a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: Not implemented.", __FUNCTION__ ); 1148a94683196406b83b14218d1beef66067f126a16keunyoung 1158a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 1168a94683196406b83b14218d1beef66067f126a16keunyoung} 1178a94683196406b83b14218d1beef66067f126a16keunyoung 1188a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 1198a94683196406b83b14218d1beef66067f126a16keunyoungset_light_keyboard( struct light_device_t* dev, struct light_state_t const* state ) 1208a94683196406b83b14218d1beef66067f126a16keunyoung{ 1218a94683196406b83b14218d1beef66067f126a16keunyoung /* @Waiting for later implementation. */ 1228a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: Not implemented.", __FUNCTION__ ); 1238a94683196406b83b14218d1beef66067f126a16keunyoung 1248a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 1258a94683196406b83b14218d1beef66067f126a16keunyoung} 1268a94683196406b83b14218d1beef66067f126a16keunyoung 1278a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 1288a94683196406b83b14218d1beef66067f126a16keunyoungset_light_notifications( struct light_device_t* dev, struct light_state_t const* state ) 1298a94683196406b83b14218d1beef66067f126a16keunyoung{ 1308a94683196406b83b14218d1beef66067f126a16keunyoung /* @Waiting for later implementation. */ 1318a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: Not implemented.", __FUNCTION__ ); 1328a94683196406b83b14218d1beef66067f126a16keunyoung 1338a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 1348a94683196406b83b14218d1beef66067f126a16keunyoung} 1358a94683196406b83b14218d1beef66067f126a16keunyoung 1368a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 1378a94683196406b83b14218d1beef66067f126a16keunyoungset_light_attention( struct light_device_t* dev, struct light_state_t const* state ) 1388a94683196406b83b14218d1beef66067f126a16keunyoung{ 1398a94683196406b83b14218d1beef66067f126a16keunyoung /* @Waiting for later implementation. */ 1408a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: Not implemented.", __FUNCTION__ ); 1418a94683196406b83b14218d1beef66067f126a16keunyoung 1428a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 1438a94683196406b83b14218d1beef66067f126a16keunyoung} 1448a94683196406b83b14218d1beef66067f126a16keunyoung 1458a94683196406b83b14218d1beef66067f126a16keunyoung/** Close the lights device */ 1468a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 1478a94683196406b83b14218d1beef66067f126a16keunyoungclose_lights( struct light_device_t *dev ) 1488a94683196406b83b14218d1beef66067f126a16keunyoung{ 1498a94683196406b83b14218d1beef66067f126a16keunyoung free( dev ); 1508a94683196406b83b14218d1beef66067f126a16keunyoung 1518a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 1528a94683196406b83b14218d1beef66067f126a16keunyoung} 1538a94683196406b83b14218d1beef66067f126a16keunyoung 1548a94683196406b83b14218d1beef66067f126a16keunyoung/** 1558a94683196406b83b14218d1beef66067f126a16keunyoung * module methods 1568a94683196406b83b14218d1beef66067f126a16keunyoung */ 1578a94683196406b83b14218d1beef66067f126a16keunyoung 1588a94683196406b83b14218d1beef66067f126a16keunyoung/** Open a new instance of a lights device using name */ 1598a94683196406b83b14218d1beef66067f126a16keunyoungstatic int 1608a94683196406b83b14218d1beef66067f126a16keunyoungopen_lights( const struct hw_module_t* module, char const *name, 1618a94683196406b83b14218d1beef66067f126a16keunyoung struct hw_device_t **device ) 1628a94683196406b83b14218d1beef66067f126a16keunyoung{ 1638a94683196406b83b14218d1beef66067f126a16keunyoung void* set_light; 1648a94683196406b83b14218d1beef66067f126a16keunyoung 1658a94683196406b83b14218d1beef66067f126a16keunyoung if (0 == strcmp( LIGHT_ID_BACKLIGHT, name )) { 1668a94683196406b83b14218d1beef66067f126a16keunyoung set_light = set_light_backlight; 1678a94683196406b83b14218d1beef66067f126a16keunyoung } else if (0 == strcmp( LIGHT_ID_KEYBOARD, name )) { 1688a94683196406b83b14218d1beef66067f126a16keunyoung set_light = set_light_keyboard; 1698a94683196406b83b14218d1beef66067f126a16keunyoung } else if (0 == strcmp( LIGHT_ID_BUTTONS, name )) { 1708a94683196406b83b14218d1beef66067f126a16keunyoung set_light = set_light_buttons; 1718a94683196406b83b14218d1beef66067f126a16keunyoung } else if (0 == strcmp( LIGHT_ID_BATTERY, name )) { 1728a94683196406b83b14218d1beef66067f126a16keunyoung set_light = set_light_battery; 1738a94683196406b83b14218d1beef66067f126a16keunyoung } else if (0 == strcmp( LIGHT_ID_NOTIFICATIONS, name )) { 1748a94683196406b83b14218d1beef66067f126a16keunyoung set_light = set_light_notifications; 1758a94683196406b83b14218d1beef66067f126a16keunyoung } else if (0 == strcmp( LIGHT_ID_ATTENTION, name )) { 1768a94683196406b83b14218d1beef66067f126a16keunyoung set_light = set_light_attention; 1778a94683196406b83b14218d1beef66067f126a16keunyoung } else { 1788a94683196406b83b14218d1beef66067f126a16keunyoung D( "%s: %s light isn't supported yet.", __FUNCTION__, name ); 1798a94683196406b83b14218d1beef66067f126a16keunyoung return -EINVAL; 1808a94683196406b83b14218d1beef66067f126a16keunyoung } 1818a94683196406b83b14218d1beef66067f126a16keunyoung 1828a94683196406b83b14218d1beef66067f126a16keunyoung struct light_device_t *dev = malloc( sizeof(struct light_device_t) ); 1838a94683196406b83b14218d1beef66067f126a16keunyoung if (dev == NULL) { 1848a94683196406b83b14218d1beef66067f126a16keunyoung return -EINVAL; 1858a94683196406b83b14218d1beef66067f126a16keunyoung } 1868a94683196406b83b14218d1beef66067f126a16keunyoung memset( dev, 0, sizeof(*dev) ); 1878a94683196406b83b14218d1beef66067f126a16keunyoung 1888a94683196406b83b14218d1beef66067f126a16keunyoung dev->common.tag = HARDWARE_DEVICE_TAG; 1898a94683196406b83b14218d1beef66067f126a16keunyoung dev->common.version = 0; 1908a94683196406b83b14218d1beef66067f126a16keunyoung dev->common.module = (struct hw_module_t*)module; 1918a94683196406b83b14218d1beef66067f126a16keunyoung dev->common.close = (int (*)(struct hw_device_t*))close_lights; 1928a94683196406b83b14218d1beef66067f126a16keunyoung dev->set_light = set_light; 1938a94683196406b83b14218d1beef66067f126a16keunyoung 1948a94683196406b83b14218d1beef66067f126a16keunyoung *device = (struct hw_device_t*)dev; 1958a94683196406b83b14218d1beef66067f126a16keunyoung return 0; 1968a94683196406b83b14218d1beef66067f126a16keunyoung} 1978a94683196406b83b14218d1beef66067f126a16keunyoung 1988a94683196406b83b14218d1beef66067f126a16keunyoungstatic struct hw_module_methods_t lights_module_methods = { 1998a94683196406b83b14218d1beef66067f126a16keunyoung .open = open_lights, 2008a94683196406b83b14218d1beef66067f126a16keunyoung}; 2018a94683196406b83b14218d1beef66067f126a16keunyoung 2028a94683196406b83b14218d1beef66067f126a16keunyoung/* 2038a94683196406b83b14218d1beef66067f126a16keunyoung * The emulator lights Module 2048a94683196406b83b14218d1beef66067f126a16keunyoung */ 2058a94683196406b83b14218d1beef66067f126a16keunyoungstruct hw_module_t HAL_MODULE_INFO_SYM = { 2068a94683196406b83b14218d1beef66067f126a16keunyoung .tag = HARDWARE_MODULE_TAG, 2078a94683196406b83b14218d1beef66067f126a16keunyoung .version_major = 1, 2088a94683196406b83b14218d1beef66067f126a16keunyoung .version_minor = 0, 2098a94683196406b83b14218d1beef66067f126a16keunyoung .id = LIGHTS_HARDWARE_MODULE_ID, 2108a94683196406b83b14218d1beef66067f126a16keunyoung .name = "Goldfish lights Module", 2118a94683196406b83b14218d1beef66067f126a16keunyoung .author = "The Android Open Source Project", 2128a94683196406b83b14218d1beef66067f126a16keunyoung .methods = &lights_module_methods, 2138a94683196406b83b14218d1beef66067f126a16keunyoung}; 214