19877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* Copyright (C) 2009 The Android Open Source Project 29877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** 39877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** This software is licensed under the terms of the GNU General Public 49877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 59877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** may be copied, distributed, and modified under those terms. 69877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** 79877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** This program is distributed in the hope that it will be useful, 89877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 99877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 109877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project** GNU General Public License for more details. 119877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project*/ 129877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 13593d0ea0d2c851f099c5e7d16cbebc992b0bf152David 'Digit' Turner#include <math.h> 149877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "android/hw-sensors.h" 159877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "android/utils/debug.h" 169877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "android/utils/misc.h" 175998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner#include "android/utils/system.h" 189877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "android/hw-qemud.h" 199877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "android/globals.h" 20871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije#include "hw/hw.h" 219877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "qemu-char.h" 229877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "qemu-timer.h" 23db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine#include "android/sensors-port.h" 249877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 25db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine#define E(...) derror(__VA_ARGS__) 26db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine#define W(...) dwarning(__VA_ARGS__) 279877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#define D(...) VERBOSE_PRINT(sensors,__VA_ARGS__) 28bc456c52dcb71007841b734195f712191012c537Vladimir Chtchetkine#define V(...) VERBOSE_PRINT(init,__VA_ARGS__) 299877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 309877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* define T_ACTIVE to 1 to debug transport communications */ 319877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#define T_ACTIVE 0 329877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 339877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#if T_ACTIVE 349877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#define T(...) VERBOSE_PRINT(sensors,__VA_ARGS__) 359877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#else 369877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#define T(...) ((void)0) 379877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#endif 389877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 399877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* this code supports emulated sensor hardware 409877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 419877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * Note that currently, only the accelerometer is really emulated, and only 429877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * for the purpose of allowing auto-rotating the screen in keyboard-less 439877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * configurations. 449877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 459877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 469877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 479877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 489877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 499877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic const struct { 509877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project const char* name; 519877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project int id; 529877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} _sSensors[MAX_SENSORS] = { 539877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#define SENSOR_(x,y) { y, ANDROID_SENSOR_##x }, 549877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project SENSORS_LIST 559877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#undef SENSOR_ 569877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project}; 579877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 589877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 599877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic int 609877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project_sensorIdFromName( const char* name ) 619877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 629877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project int nn; 639877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project for (nn = 0; nn < MAX_SENSORS; nn++) 649877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (!strcmp(_sSensors[nn].name,name)) 659877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return _sSensors[nn].id; 669877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return -1; 679877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 689877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 69736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanstatic const char* 70736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan_sensorNameFromId( int id ) 71736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan{ 72736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan int nn; 73736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan for (nn = 0; nn < MAX_SENSORS; nn++) 74736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (id == _sSensors[nn].id) 75736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return _sSensors[nn].name; 76736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return NULL; 77736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan} 78736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 79736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan/* For common Sensor Value struct */ 80736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wantypedef struct { 81736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan float a, b, c; 82736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan} SensorValues; 839877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 849877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projecttypedef struct { 859877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project float x, y, z; 869877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} Acceleration; 879877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 889877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 899877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projecttypedef struct { 909877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project float x, y, z; 919877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} MagneticField; 929877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 939877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 949877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projecttypedef struct { 959877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project float azimuth; 969877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project float pitch; 979877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project float roll; 989877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} Orientation; 999877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1009877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1019877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projecttypedef struct { 1029877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project float celsius; 1039877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} Temperature; 1049877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1059877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1069877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projecttypedef struct { 1077c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson float value; 1087c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson} Proximity; 1097c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson 1107c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertssontypedef struct { 1117c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson char enabled; 1129877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project union { 113736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan SensorValues value; 1149877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project Acceleration acceleration; 1159877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project MagneticField magnetic; 1169877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project Orientation orientation; 1179877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project Temperature temperature; 1187c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson Proximity proximity; 1199877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } u; 1209877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} Sensor; 1219877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1229877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* 1239877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * - when the qemu-specific sensors HAL module starts, it sends 1249877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * "list-sensors" 1259877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1269877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * - this code replies with a string containing an integer corresponding 1279877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * to a bitmap of available hardware sensors in the current AVD 1289877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * configuration (e.g. "1" a.k.a (1 << ANDROID_SENSOR_ACCELERATION)) 1299877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1309877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * - the HAL module sends "set:<sensor>:<flag>" to enable or disable 1319877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * the report of a given sensor state. <sensor> must be the name of 1329877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * a given sensor (e.g. "accelerometer"), and <flag> must be either 1339877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * "1" (to enable) or "0" (to disable). 1349877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1359877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * - Once at least one sensor is "enabled", this code should periodically 1369877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * send information about the corresponding enabled sensors. The default 1379877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * period is 200ms. 1389877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1399877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * - the HAL module sends "set-delay:<delay>", where <delay> is an integer 1409877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * corresponding to a time delay in milli-seconds. This corresponds to 1419877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * a new interval between sensor events sent by this code to the HAL 1429877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * module. 1439877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1449877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * - the HAL module can also send a "wake" command. This code should simply 1459877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * send the "wake" back to the module. This is used internally to wake a 1469877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * blocking read that happens in a different thread. This ping-pong makes 1479877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * the code in the HAL module very simple. 1489877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1499877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * - each timer tick, this code sends sensor reports in the following 1509877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * format (each line corresponds to a different line sent to the module): 1519877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1529877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * acceleration:<x>:<y>:<z> 1539877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * magnetic-field:<x>:<y>:<z> 1549877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * orientation:<azimuth>:<pitch>:<roll> 1559877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * temperature:<celsius> 1569877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * sync:<time_us> 1579877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1589877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * Where each line before the sync:<time_us> is optional and will only 1599877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * appear if the corresponding sensor has been enabled by the HAL module. 1609877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * 1619877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * Note that <time_us> is the VM time in micro-seconds when the report 1629877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * was "taken" by this code. This is adjusted by the HAL module to 1639877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * emulated system time (using the first sync: to compute an adjustment 1649877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * offset). 1659877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 1669877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#define HEADER_SIZE 4 1679877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#define BUFFER_SIZE 512 1689877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1695998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnertypedef struct HwSensorClient HwSensorClient; 1705998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 1719877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projecttypedef struct { 172db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine QemudService* service; 173db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine Sensor sensors[MAX_SENSORS]; 174db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine HwSensorClient* clients; 175db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine AndroidSensorsPort* sensors_port; 1769877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} HwSensors; 1779877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1785998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstruct HwSensorClient { 1795998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient* next; 1805998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensors* sensors; 1815998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner QemudClient* client; 1825998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner QEMUTimer* timer; 1835998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner uint32_t enabledMask; 1845998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner int32_t delay_ms; 1855998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner}; 1869877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 1879877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void 1885998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_free( HwSensorClient* cl ) 1899877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 1905998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner /* remove from sensors's list */ 1915998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (cl->sensors) { 1925998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient** pnode = &cl->sensors->clients; 1935998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner for (;;) { 1945998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient* node = *pnode; 1955998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (node == NULL) 1965998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner break; 1975998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (node == cl) { 1985998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner *pnode = cl->next; 1995998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner break; 2005998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 2015998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner pnode = &node->next; 2025998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 2035998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->next = NULL; 2045998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->sensors = NULL; 2055998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 2069877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2075998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner /* close QEMUD client, if any */ 2085998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (cl->client) { 2095998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner qemud_client_close(cl->client); 2105998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->client = NULL; 2115998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 2125998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner /* remove timer, if any */ 2135998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (cl->timer) { 2145998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner qemu_del_timer(cl->timer); 2155998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner qemu_free_timer(cl->timer); 2165998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->timer = NULL; 2175998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 2185998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner AFREE(cl); 2199877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 2209877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2215998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner/* forward */ 2225998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic void _hwSensorClient_tick(void* opaque); 2239877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2249877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2255998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic HwSensorClient* 2265998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_new( HwSensors* sensors ) 2279877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 2285998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient* cl; 2299877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2305998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner ANEW0(cl); 2315998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2325998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->sensors = sensors; 2335998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->enabledMask = 0; 234593d0ea0d2c851f099c5e7d16cbebc992b0bf152David 'Digit' Turner cl->delay_ms = 800; 2355973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner cl->timer = qemu_new_timer_ns(vm_clock, _hwSensorClient_tick, cl); 2365998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2375998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->next = sensors->clients; 2385998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner sensors->clients = cl; 2395998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2405998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner return cl; 2419877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 2429877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2435998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner/* forward */ 2445998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2455998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic void _hwSensorClient_receive( HwSensorClient* cl, 2465998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner uint8_t* query, 2475998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner int querylen ); 2485998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2495998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner/* Qemud service management */ 2505998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2519877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void 2525998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_recv( void* opaque, uint8_t* msg, int msglen, 2535998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner QemudClient* client ) 2549877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 2555998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient* cl = opaque; 2569877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2575998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_receive(cl, msg, msglen); 2589877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 2599877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2609877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void 2615998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_close( void* opaque ) 2629877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 2635998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient* cl = opaque; 2649877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2655998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner /* the client is already closed here */ 2665998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->client = NULL; 2675998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_free(cl); 2689877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 2699877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2709877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* send a one-line message to the HAL module through a qemud channel */ 2719877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void 2725998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_send( HwSensorClient* cl, const uint8_t* msg, int msglen ) 2739877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 2749877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project D("%s: '%s'", __FUNCTION__, quote_bytes((const void*)msg, msglen)); 2755998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner qemud_client_send(cl->client, msg, msglen); 2765998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner} 2775998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2785998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic int 2795998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_enabled( HwSensorClient* cl, int sensorId ) 2805998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner{ 2815998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner return (cl->enabledMask & (1 << sensorId)) != 0; 2829877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 2839877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 2849877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* this function is called periodically to send sensor reports 2859877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * to the HAL module, and re-arm the timer if necessary 2869877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 2879877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void 2885998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_tick( void* opaque ) 2899877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 2905998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient* cl = opaque; 2915998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensors* hw = cl->sensors; 2925998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner int64_t delay = cl->delay_ms; 2935998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner int64_t now_ns; 2945998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner uint32_t mask = cl->enabledMask; 2955998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner Sensor* sensor; 2965998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner char buffer[128]; 2975998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 2985998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ACCELERATION)) { 2995998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner sensor = &hw->sensors[ANDROID_SENSOR_ACCELERATION]; 3009877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project snprintf(buffer, sizeof buffer, "acceleration:%g:%g:%g", 3019877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.acceleration.x, 3029877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.acceleration.y, 3039877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.acceleration.z); 3045998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); 3059877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 3069877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3075998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_MAGNETIC_FIELD)) { 3085998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner sensor = &hw->sensors[ANDROID_SENSOR_MAGNETIC_FIELD]; 309db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine /* NOTE: sensors HAL expects "magnetic", not "magnetic-field" name here. */ 310db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine snprintf(buffer, sizeof buffer, "magnetic:%g:%g:%g", 3119877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.magnetic.x, 3129877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.magnetic.y, 3139877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.magnetic.z); 3145998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); 3159877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 3169877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3175998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ORIENTATION)) { 3185998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner sensor = &hw->sensors[ANDROID_SENSOR_ORIENTATION]; 3199877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project snprintf(buffer, sizeof buffer, "orientation:%g:%g:%g", 3209877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.orientation.azimuth, 3219877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.orientation.pitch, 3229877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.orientation.roll); 3235998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); 3249877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 3259877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3265998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_TEMPERATURE)) { 3275998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner sensor = &hw->sensors[ANDROID_SENSOR_TEMPERATURE]; 3289877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project snprintf(buffer, sizeof buffer, "temperature:%g", 3299877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project sensor->u.temperature.celsius); 3305998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); 3319877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 3329877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3337c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_PROXIMITY)) { 3347c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson sensor = &hw->sensors[ANDROID_SENSOR_PROXIMITY]; 3357c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson snprintf(buffer, sizeof buffer, "proximity:%g", 3367c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson sensor->u.proximity.value); 3377c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson _hwSensorClient_send(cl, (uint8_t*) buffer, strlen(buffer)); 3387c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson } 3397c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson 3405973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner now_ns = qemu_get_clock_ns(vm_clock); 3419877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 342c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh snprintf(buffer, sizeof buffer, "sync:%" PRId64, now_ns/1000); 3435998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); 3449877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3459877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project /* rearm timer, use a minimum delay of 20 ms, just to 3469877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * be safe. 3479877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 3489877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (mask == 0) 3499877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return; 3509877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3519877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (delay < 20) 3529877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project delay = 20; 3539877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3549877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project delay *= 1000000LL; /* convert to nanoseconds */ 3555998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner qemu_mod_timer(cl->timer, now_ns + delay); 3569877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 3579877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3589877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* handle incoming messages from the HAL module */ 3599877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void 3605998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensorClient_receive( HwSensorClient* cl, uint8_t* msg, int msglen ) 3619877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 3625998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensors* hw = cl->sensors; 3635998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 3649877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project D("%s: '%.*s'", __FUNCTION__, msglen, msg); 3659877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3669877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project /* "list-sensors" is used to get an integer bit map of 3679877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * available emulated sensors. We compute the mask from the 3689877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * current hardware configuration. 3699877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 3709877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (msglen == 12 && !memcmp(msg, "list-sensors", 12)) { 3719877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project char buff[12]; 3729877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project int mask = 0; 3735998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner int nn; 3749877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3755998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner for (nn = 0; nn < MAX_SENSORS; nn++) { 3765998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (hw->sensors[nn].enabled) 3775998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner mask |= (1 << nn); 3785998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 3799877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3809877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project snprintf(buff, sizeof buff, "%d", mask); 3815998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_send(cl, (const uint8_t*)buff, strlen(buff)); 3829877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return; 3839877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 3849877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3859877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project /* "wake" is a special message that must be sent back through 3869877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * the channel. It is used to exit a blocking read. 3879877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 3889877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (msglen == 4 && !memcmp(msg, "wake", 4)) { 3895998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_send(cl, (const uint8_t*)"wake", 4); 3909877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return; 3919877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 3929877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 3939877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project /* "set-delay:<delay>" is used to set the delay in milliseconds 3949877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * between sensor events 3959877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 3969877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (msglen > 10 && !memcmp(msg, "set-delay:", 10)) { 3975998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->delay_ms = atoi((const char*)msg+10); 3985998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (cl->enabledMask != 0) 3995998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_tick(cl); 4009877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4019877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return; 4029877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 4039877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4049877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project /* "set:<name>:<state>" is used to enable/disable a given 4059877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project * sensor. <state> must be 0 or 1 4069877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project */ 4079877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (msglen > 4 && !memcmp(msg, "set:", 4)) { 4089877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project char* q; 4095998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner int id, enabled, oldEnabledMask = cl->enabledMask; 4109877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project msg += 4; 4119877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project q = strchr((char*)msg, ':'); 4129877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (q == NULL) { /* should not happen */ 4139877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project D("%s: ignore bad 'set' command", __FUNCTION__); 4149877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return; 4159877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 4169877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project *q++ = 0; 4179877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4189877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project id = _sensorIdFromName((const char*)msg); 4195998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (id < 0 || id >= MAX_SENSORS) { 4209877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project D("%s: ignore unknown sensor name '%s'", __FUNCTION__, msg); 4219877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return; 4229877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 4239877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4245998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (!hw->sensors[id].enabled) { 4255998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner D("%s: trying to set disabled %s sensor", __FUNCTION__, msg); 4265998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner return; 4275998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 4289877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project enabled = (q[0] == '1'); 4299877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4309877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (enabled) 4315998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->enabledMask |= (1 << id); 4329877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project else 4335998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->enabledMask &= ~(1 << id); 4349877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4355998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner if (cl->enabledMask != oldEnabledMask) { 4365998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner D("%s: %s %s sensor", __FUNCTION__, 4375998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner (cl->enabledMask & (1 << id)) ? "enabling" : "disabling", msg); 4389877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 439db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine 440db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine /* If emulating device is connected update sensor state there too. */ 4417136b053b7fc7840ec64e01d1d19ab822e1f949aVladimir Chtchetkine if (hw->sensors_port != NULL) { 442db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine if (enabled) { 443db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine sensors_port_enable_sensor(hw->sensors_port, (const char*)msg); 444db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } else { 445db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine sensors_port_disable_sensor(hw->sensors_port, (const char*)msg); 446db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 447db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 448db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine 4495998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_tick(cl); 4509877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project return; 4519877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 4529877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4539877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project D("%s: ignoring unknown query", __FUNCTION__); 4549877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 4559877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 456871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije/* Saves sensor-specific client data to snapshot */ 457871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thijestatic void 458871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije_hwSensorClient_save( QEMUFile* f, QemudClient* client, void* opaque ) 459871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije{ 460871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije HwSensorClient* sc = opaque; 461871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 462871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_be32(f, sc->delay_ms); 463871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_be32(f, sc->enabledMask); 464871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_timer(f, sc->timer); 465871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije} 466871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 467871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije/* Loads sensor-specific client data from snapshot */ 468871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thijestatic int 469871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije_hwSensorClient_load( QEMUFile* f, QemudClient* client, void* opaque ) 470871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije{ 471871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije HwSensorClient* sc = opaque; 472871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 473871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije sc->delay_ms = qemu_get_be32(f); 474871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije sc->enabledMask = qemu_get_be32(f); 475871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_get_timer(f, sc->timer); 476871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 477871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije return 0; 478871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije} 4799877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 4805998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic QemudClient* 4814c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine_hwSensors_connect( void* opaque, 4824c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine QemudService* service, 4834c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine int channel, 4844c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine const char* client_param ) 4855998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner{ 4865998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensors* sensors = opaque; 4875998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner HwSensorClient* cl = _hwSensorClient_new(sensors); 4884c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine QemudClient* client = qemud_client_new(service, channel, client_param, cl, 4895998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensorClient_recv, 490871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije _hwSensorClient_close, 491871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije _hwSensorClient_save, 492871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije _hwSensorClient_load ); 4935998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner qemud_client_set_framing(client, 1); 4945998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner cl->client = client; 4955998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 4965998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner return client; 4975998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner} 4985998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 499736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan/* change the value of the emulated sensor vector */ 5005998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic void 501736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan_hwSensors_setSensorValue( HwSensors* h, int sensor_id, float a, float b, float c ) 5025998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner{ 503736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan Sensor* s = &h->sensors[sensor_id]; 504736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 505736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan s->u.value.a = a; 506736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan s->u.value.b = b; 507736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan s->u.value.c = c; 5085998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner} 5095998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 510871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije/* Saves available sensors to allow checking availability when loaded. 511871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije */ 512871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thijestatic void 513871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije_hwSensors_save( QEMUFile* f, QemudService* sv, void* opaque) 514871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije{ 515871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije HwSensors* h = opaque; 516871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 517871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije // number of sensors 518871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_be32(f, MAX_SENSORS); 519871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije AndroidSensor i; 520871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije for (i = 0 ; i < MAX_SENSORS; i++) { 521871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije Sensor* s = &h->sensors[i]; 522871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_be32(f, s->enabled); 523871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 524871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije /* this switch ensures that a warning is raised when a new sensor is 525871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije * added and is not added here as well. 526871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije */ 527871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije switch (i) { 528871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_ACCELERATION: 529871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.acceleration.x); 530871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.acceleration.y); 531871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.acceleration.z); 532871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 533871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_MAGNETIC_FIELD: 534871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.magnetic.x); 535871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.magnetic.y); 536871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.magnetic.z); 537871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 538871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_ORIENTATION: 539871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.orientation.azimuth); 540871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.orientation.pitch); 541871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.orientation.roll); 542871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 543871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_TEMPERATURE: 544871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije qemu_put_float(f, s->u.temperature.celsius); 545871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 5467c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson case ANDROID_SENSOR_PROXIMITY: 5477c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson qemu_put_float(f, s->u.proximity.value); 5487c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson break; 549871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case MAX_SENSORS: 550871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 551871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije } 552871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije } 553871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije} 554871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 555871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 556871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thijestatic int 557871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije_hwSensors_load( QEMUFile* f, QemudService* s, void* opaque) 558871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije{ 559871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije HwSensors* h = opaque; 560871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 561871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije /* check number of sensors */ 562871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije int32_t num_sensors = qemu_get_be32(f); 563607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner if (num_sensors > MAX_SENSORS) { 564871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije D("%s: cannot load: snapshot requires %d sensors, %d available\n", 565871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije __FUNCTION__, num_sensors, MAX_SENSORS); 566871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije return -EIO; 567871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije } 568871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 569871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije /* load sensor state */ 570871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije AndroidSensor i; 571607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner for (i = 0 ; i < num_sensors; i++) { 572871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije Sensor* s = &h->sensors[i]; 573871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->enabled = qemu_get_be32(f); 574871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 575871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije /* this switch ensures that a warning is raised when a new sensor is 576871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije * added and is not added here as well. 577871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije */ 578871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije switch (i) { 579871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_ACCELERATION: 580871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.acceleration.x = qemu_get_float(f); 581871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.acceleration.y = qemu_get_float(f); 582871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.acceleration.z = qemu_get_float(f); 583871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 584871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_MAGNETIC_FIELD: 585871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.magnetic.x = qemu_get_float(f); 586871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.magnetic.y = qemu_get_float(f); 587871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.magnetic.z = qemu_get_float(f); 588871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 589871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_ORIENTATION: 590871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.orientation.azimuth = qemu_get_float(f); 591871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.orientation.pitch = qemu_get_float(f); 592871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.orientation.roll = qemu_get_float(f); 593871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 594871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case ANDROID_SENSOR_TEMPERATURE: 595871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije s->u.temperature.celsius = qemu_get_float(f); 596871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 5977c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson case ANDROID_SENSOR_PROXIMITY: 5987c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson s->u.proximity.value = qemu_get_float(f); 5997c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson break; 600871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije case MAX_SENSORS: 601871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije break; 602871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije } 603871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije } 604871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 605607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner /* The following is necessary when we resume a snaphost 606607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner * created by an older version of the emulator that provided 607607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner * less hardware sensors. 608607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner */ 609607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner for ( ; i < MAX_SENSORS; i++ ) { 610607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner h->sensors[i].enabled = 0; 611607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner } 612607461d262aaa756c2ea3a9c6eb03cff38294c70David 'Digit' Turner 613871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije return 0; 614871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije} 615871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 616871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije 6177c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson/* change the emulated proximity */ 6187c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertssonstatic void 6197c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson_hwSensors_setProximity( HwSensors* h, float value ) 6207c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson{ 6217c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson Sensor* s = &h->sensors[ANDROID_SENSOR_PROXIMITY]; 6227c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson s->u.proximity.value = value; 6237c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson} 6247c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson 6255998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner/* change the coarse orientation (landscape/portrait) of the emulated device */ 6265998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic void 6275998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensors_setCoarseOrientation( HwSensors* h, AndroidCoarseOrientation orient ) 6285998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner{ 6295998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner /* The Android framework computes the orientation by looking at 6305998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * the accelerometer sensor (*not* the orientation sensor !) 6315998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * 6325998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * That's because the gravity is a constant 9.81 vector that 6335998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * can be determined quite easily. 6345998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * 6355998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * Also, for some reason, the framework code considers that the phone should 6365998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * be inclined by 30 degrees along the phone's X axis to be considered 6375998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * in its ideal "vertical" position 6385998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * 6395998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * If the phone is completely vertical, rotating it will not do anything ! 6405998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner */ 6415998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner const double g = 9.81; 642593d0ea0d2c851f099c5e7d16cbebc992b0bf152David 'Digit' Turner const double angle = 20.0; 643593d0ea0d2c851f099c5e7d16cbebc992b0bf152David 'Digit' Turner const double cos_angle = cos(angle/M_PI); 644593d0ea0d2c851f099c5e7d16cbebc992b0bf152David 'Digit' Turner const double sin_angle = sin(angle/M_PI); 6455998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 6465998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner switch (orient) { 6475998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner case ANDROID_COARSE_PORTRAIT: 648736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan _hwSensors_setSensorValue( h, ANDROID_SENSOR_ACCELERATION, 0., g*cos_angle, g*sin_angle ); 6495998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner break; 6505998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 6515998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner case ANDROID_COARSE_LANDSCAPE: 652736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan _hwSensors_setSensorValue( h, ANDROID_SENSOR_ACCELERATION, g*cos_angle, 0., g*sin_angle ); 6535998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner break; 6545998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner default: 6555998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner ; 6565998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner } 6575998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner} 6585998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 6595998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 6605998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner/* initialize the sensors state */ 6615998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turnerstatic void 6625998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner_hwSensors_init( HwSensors* h ) 6635998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner{ 664db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine /* Try to see if there is a device attached that can be used for 665db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine * sensor emulation. */ 666db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine h->sensors_port = sensors_port_create(h); 667db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine if (h->sensors_port == NULL) { 668bc456c52dcb71007841b734195f712191012c537Vladimir Chtchetkine V("Realistic sensor emulation is not available, since the remote controller is not accessible:\n %s", 669bc456c52dcb71007841b734195f712191012c537Vladimir Chtchetkine strerror(errno)); 670db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 671db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine 672871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije h->service = qemud_service_register("sensors", 0, h, _hwSensors_connect, 673871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije _hwSensors_save, _hwSensors_load); 6745998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 675db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine if (android_hw->hw_accelerometer) { 6765998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner h->sensors[ANDROID_SENSOR_ACCELERATION].enabled = 1; 677db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 6785998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 679db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine if (android_hw->hw_sensors_proximity) { 6807c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson h->sensors[ANDROID_SENSOR_PROXIMITY].enabled = 1; 681db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 682db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine 683db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine if (android_hw->hw_sensors_magnetic_field) { 684db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD].enabled = 1; 685db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 686db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine 687db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine if (android_hw->hw_sensors_orientation) { 688db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine h->sensors[ANDROID_SENSOR_ORIENTATION].enabled = 1; 689db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 690db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine 691db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine if (android_hw->hw_sensors_temperature) { 692db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine h->sensors[ANDROID_SENSOR_TEMPERATURE].enabled = 1; 693db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine } 694db611d57e0da9acd7ecf2a4a9b2a63e7620fe54dVladimir Chtchetkine 6955998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner /* XXX: TODO: Add other tests when we add the corresponding 6965998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner * properties to hardware-properties.ini et al. */ 6975998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 6985998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensors_setCoarseOrientation(h, ANDROID_COARSE_PORTRAIT); 6997c8397abd80cd6ba6a2665ef22739e603ae4c290Ola Albertsson _hwSensors_setProximity(h, 1); 7005998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner} 7015998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner 7029877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic HwSensors _sensorsState[1]; 7039877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 7049877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectvoid 7059877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectandroid_hw_sensors_init( void ) 7069877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 7079877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project HwSensors* hw = _sensorsState; 7089877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 7099877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project if (hw->service == NULL) { 7105998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensors_init(hw); 7119877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project D("%s: sensors qemud service initialized", __FUNCTION__); 7129877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project } 7139877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 7149877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 7159877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* change the coarse orientation value */ 7169877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectextern void 7179877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectandroid_sensors_set_coarse_orientation( AndroidCoarseOrientation orient ) 7189877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{ 7199877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project android_hw_sensors_init(); 7205998b8947d8c2788b62d38afdd571ddff78648a5David 'Digit' Turner _hwSensors_setCoarseOrientation(_sensorsState, orient); 7219877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project} 7229877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project 723736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan/* Get sensor name from sensor id */ 724736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanextern const char* 725736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanandroid_sensors_get_name_from_id( int sensor_id ) 726736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan{ 727736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (sensor_id < 0 || sensor_id >= MAX_SENSORS) 728736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return NULL; 729736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 730736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return _sensorNameFromId(sensor_id); 731736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan} 732736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 733736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan/* Get sensor id from sensor name */ 734736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanextern int 735736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanandroid_sensors_get_id_from_name( char* sensorname ) 736736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan{ 737736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan HwSensors* hw = _sensorsState; 738736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 739736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (sensorname == NULL) 740736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_UNKNOWN; 741736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 742736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan int id = _sensorIdFromName(sensorname); 743736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 744736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (id < 0 || id >= MAX_SENSORS) 745736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_UNKNOWN; 746736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 747736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (hw->service != NULL) { 748736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (! hw->sensors[id].enabled) 749736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_DISABLED; 750736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan } else 751736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_NO_SERVICE; 752736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 753736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return id; 754736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan} 755736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 756736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan/* Interface of reading the data for all sensors */ 757736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanextern int 758736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanandroid_sensors_get( int sensor_id, float* a, float* b, float* c ) 759736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan{ 760736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan HwSensors* hw = _sensorsState; 761736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 762736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan *a = 0; 763736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan *b = 0; 764736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan *c = 0; 765736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 766736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (sensor_id < 0 || sensor_id >= MAX_SENSORS) 767736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_UNKNOWN; 768736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 769736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan Sensor* sensor = &hw->sensors[sensor_id]; 770736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (hw->service != NULL) { 771736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (! sensor->enabled) 772736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_DISABLED; 773736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan } else 774736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_NO_SERVICE; 775736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 776736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan *a = sensor->u.value.a; 777736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan *b = sensor->u.value.b; 778736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan *c = sensor->u.value.c; 779736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 780736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_OK; 781736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan} 782736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 783736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan/* Interface of setting the data for all sensors */ 784736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanextern int 785736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanandroid_sensors_set( int sensor_id, float a, float b, float c ) 786736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan{ 787736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan HwSensors* hw = _sensorsState; 788736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 789736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (sensor_id < 0 || sensor_id >= MAX_SENSORS) 790736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_UNKNOWN; 791736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 792736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (hw->service != NULL) { 793736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (! hw->sensors[sensor_id].enabled) 794736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_DISABLED; 795736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan } else 796736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_NO_SERVICE; 797736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 798736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan _hwSensors_setSensorValue(hw, sensor_id, a, b, c); 799736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 800736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_OK; 801736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan} 802736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 803736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan/* Get Sensor from sensor id */ 804736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanextern uint8_t 805736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wanandroid_sensors_get_sensor_status( int sensor_id ) 806736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan{ 807736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan HwSensors* hw = _sensorsState; 808736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 809736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan if (sensor_id < 0 || sensor_id >= MAX_SENSORS) 810736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return SENSOR_STATUS_UNKNOWN; 811736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan 812736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan return hw->sensors[sensor_id].enabled; 813736e01f86f4ec4049bb5795f1ddb979132b05333Tim Wan} 814