Home | History | Annotate | Download | only in android
      1 /* Copyright (C) 2007-2008 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 
     13 /* this file implements the support of the new 'hardware control'
     14  * qemud communication channel, which is used by libs/hardware on
     15  * the system image to communicate with the emulator program for
     16  * emulating the following:
     17  *
     18  *   - power management
     19  *   - led(s) brightness
     20  *   - vibrator
     21  *   - flashlight
     22  */
     23 #include "android/hw-control.h"
     24 #include "cbuffer.h"
     25 #include "android/hw-qemud.h"
     26 #include "android/globals.h"
     27 #include "android/utils/misc.h"
     28 #include "android/utils/debug.h"
     29 #include "qemu-char.h"
     30 #include <stdio.h>
     31 #include <string.h>
     32 
     33 #define  D(...)  VERBOSE_PRINT(hw_control,__VA_ARGS__)
     34 
     35 /* define T_ACTIVE to 1 to debug transport communications */
     36 #define  T_ACTIVE  0
     37 
     38 #if T_ACTIVE
     39 #define  T(...)  VERBOSE_PRINT(hw_control,__VA_ARGS__)
     40 #else
     41 #define  T(...)   ((void)0)
     42 #endif
     43 
     44 typedef struct {
     45     void*                  client;
     46     AndroidHwControlFuncs  client_funcs;
     47     QemudService*          service;
     48 } HwControl;
     49 
     50 /* handle query */
     51 static void  hw_control_do_query( HwControl*  h, uint8_t*  query, int  querylen );
     52 
     53 /* called when a qemud client sends a command */
     54 static void
     55 _hw_control_qemud_client_recv( void*         opaque,
     56                                uint8_t*      msg,
     57                                int           msglen,
     58                                QemudClient*  client )
     59 {
     60     hw_control_do_query(opaque, msg, msglen);
     61 }
     62 
     63 /* called when a qemud client connects to the service */
     64 static QemudClient*
     65 _hw_control_qemud_connect( void*  opaque,
     66                            QemudService*  service,
     67                            int  channel,
     68                            const char* client_param )
     69 {
     70     QemudClient*  client;
     71 
     72     client = qemud_client_new( service, channel, client_param,
     73                                opaque,
     74                                _hw_control_qemud_client_recv,
     75                                NULL, NULL, NULL );
     76 
     77     qemud_client_set_framing(client, 1);
     78     return client;
     79 }
     80 
     81 
     82 static uint8_t*
     83 if_starts_with( uint8_t*  buf, int buflen, const char*  prefix )
     84 {
     85     int  prefixlen = strlen(prefix);
     86 
     87     if (buflen < prefixlen || memcmp(buf, prefix, prefixlen))
     88         return NULL;
     89 
     90     return (uint8_t*)buf + prefixlen;
     91 }
     92 
     93 
     94 static void
     95 hw_control_do_query( HwControl*  h,
     96                      uint8_t*    query,
     97                      int         querylen )
     98 {
     99     uint8_t*   q;
    100 
    101     T("%s: query %4d '%.*s'", __FUNCTION__, querylen, querylen, query );
    102 
    103     q = if_starts_with( query, querylen, "power:light:brightness:" );
    104     if (q != NULL) {
    105         if (h->client_funcs.light_brightness && android_hw->hw_lcd_backlight) {
    106             char*  qq = strchr((const char*)q, ':');
    107             int    value;
    108             if (qq == NULL) {
    109                 D("%s: badly formatted", __FUNCTION__ );
    110                 return;
    111             }
    112             *qq++ = 0;
    113             value = atoi(qq);
    114             h->client_funcs.light_brightness( h->client, (char*)q, value );
    115         }
    116         return;
    117     }
    118 }
    119 
    120 
    121 static void
    122 hw_control_init( HwControl*                    control,
    123                  void*                         client,
    124                  const AndroidHwControlFuncs*  client_funcs )
    125 {
    126     control->client       = client;
    127     control->client_funcs = client_funcs[0];
    128     control->service      = qemud_service_register( "hw-control", 0,
    129                                                     control,
    130                                                     _hw_control_qemud_connect,
    131                                                     NULL, NULL);
    132 }
    133 
    134 const AndroidHwControlFuncs  defaultControls = {
    135     NULL,
    136 };
    137 
    138 static HwControl   hwstate[1];
    139 
    140 void
    141 android_hw_control_init( void )
    142 {
    143     hw_control_init(hwstate, NULL, &defaultControls);
    144     D("%s: hw-control qemud handler initialized", __FUNCTION__);
    145 }
    146 
    147 void
    148 android_hw_control_set( void*  opaque, const AndroidHwControlFuncs*  funcs )
    149 {
    150     hwstate->client       = opaque;
    151     hwstate->client_funcs = funcs[0];
    152 }
    153 
    154