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