The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 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" |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 25 | #include "android/hw-qemud.h" |
Tim Wan | 470f6bd | 2011-04-13 15:18:08 +0200 | [diff] [blame] | 26 | #include "android/globals.h" |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 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 | |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 44 | typedef struct { |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 45 | void* client; |
| 46 | AndroidHwControlFuncs client_funcs; |
| 47 | QemudService* service; |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 48 | } HwControl; |
| 49 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 50 | /* handle query */ |
| 51 | static void hw_control_do_query( HwControl* h, uint8_t* query, int querylen ); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 52 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 53 | /* called when a qemud client sends a command */ |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 54 | static void |
David 'Digit' Turner | 318e4f2 | 2009-05-25 18:01:03 +0200 | [diff] [blame] | 55 | _hw_control_qemud_client_recv( void* opaque, |
| 56 | uint8_t* msg, |
| 57 | int msglen, |
| 58 | QemudClient* client ) |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 59 | { |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 60 | hw_control_do_query(opaque, msg, msglen); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 61 | } |
| 62 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 63 | /* called when a qemud client connects to the service */ |
| 64 | static QemudClient* |
| 65 | _hw_control_qemud_connect( void* opaque, QemudService* service, int channel ) |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 66 | { |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 67 | QemudClient* client; |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 68 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 69 | client = qemud_client_new( service, channel, |
| 70 | opaque, |
| 71 | _hw_control_qemud_client_recv, |
Ot ten Thije | 871da2a | 2010-09-20 10:29:22 +0100 | [diff] [blame] | 72 | NULL, NULL, NULL ); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 73 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 74 | qemud_client_set_framing(client, 1); |
| 75 | return client; |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | |
| 79 | static uint8_t* |
| 80 | if_starts_with( uint8_t* buf, int buflen, const char* prefix ) |
| 81 | { |
| 82 | int prefixlen = strlen(prefix); |
| 83 | |
| 84 | if (buflen < prefixlen || memcmp(buf, prefix, prefixlen)) |
| 85 | return NULL; |
| 86 | |
| 87 | return (uint8_t*)buf + prefixlen; |
| 88 | } |
| 89 | |
| 90 | |
| 91 | static void |
| 92 | hw_control_do_query( HwControl* h, |
| 93 | uint8_t* query, |
| 94 | int querylen ) |
| 95 | { |
| 96 | uint8_t* q; |
| 97 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 98 | T("%s: query %4d '%.*s'", __FUNCTION__, querylen, querylen, query ); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 99 | |
| 100 | q = if_starts_with( query, querylen, "power:light:brightness:" ); |
| 101 | if (q != NULL) { |
Tim Wan | 470f6bd | 2011-04-13 15:18:08 +0200 | [diff] [blame] | 102 | if (h->client_funcs.light_brightness && android_hw->hw_lcd_backlight) { |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 103 | char* qq = strchr((const char*)q, ':'); |
| 104 | int value; |
| 105 | if (qq == NULL) { |
| 106 | D("%s: badly formatted", __FUNCTION__ ); |
| 107 | return; |
| 108 | } |
| 109 | *qq++ = 0; |
| 110 | value = atoi(qq); |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 111 | h->client_funcs.light_brightness( h->client, (char*)q, value ); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 112 | } |
| 113 | return; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 118 | static void |
| 119 | hw_control_init( HwControl* control, |
| 120 | void* client, |
| 121 | const AndroidHwControlFuncs* client_funcs ) |
| 122 | { |
| 123 | control->client = client; |
| 124 | control->client_funcs = client_funcs[0]; |
| 125 | control->service = qemud_service_register( "hw-control", 0, |
| 126 | control, |
Ot ten Thije | 871da2a | 2010-09-20 10:29:22 +0100 | [diff] [blame] | 127 | _hw_control_qemud_connect, |
| 128 | NULL, NULL); |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 129 | } |
| 130 | |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 131 | void |
| 132 | android_hw_control_init( void* opaque, const AndroidHwControlFuncs* funcs ) |
| 133 | { |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 134 | static HwControl hwstate[1]; |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 135 | |
The Android Open Source Project | 9877e2e | 2009-03-18 17:39:44 -0700 | [diff] [blame] | 136 | hw_control_init(hwstate, opaque, funcs); |
| 137 | D("%s: hw-control qemud handler initialized", __FUNCTION__); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 138 | } |