diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:50 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:50 -0800 |
commit | 51704bed795b5b0e5e3c7b792dcdc2bf2d96a9e9 (patch) | |
tree | 57cf7487c9e5e66c3c2d8b4e0cebe30e1662a02c | |
parent | d6054a36475b5ff502b4af78f7d272a713c1a8e7 (diff) | |
download | hardware_libhardware-51704bed795b5b0e5e3c7b792dcdc2bf2d96a9e9.zip hardware_libhardware-51704bed795b5b0e5e3c7b792dcdc2bf2d96a9e9.tar.gz hardware_libhardware-51704bed795b5b0e5e3c7b792dcdc2bf2d96a9e9.tar.bz2 |
Code drop from //branches/cupcake/...@124589
40 files changed, 2506 insertions, 1046 deletions
@@ -8,12 +8,25 @@ include $(CLEAR_VARS) LOCAL_SHARED_LIBRARIES := libutils libcutils libwpa_client +LOCAL_INCLUDES += $(LOCAL_PATH) + +ifneq ($(TARGET_SIMULATOR),true) + LOCAL_CFLAGS += -DQEMU_HARDWARE + QEMU_HARDWARE := true +endif + +ifneq ($(TARGET_SIMULATOR),true) +LOCAL_SHARED_LIBRARIES += libdl +endif + include $(SAVE_MAKEFILES) +LOCAL_SRC_FILES += hardware.c + # need "-lrt" on Linux simulator to pick up clock_gettime ifeq ($(TARGET_SIMULATOR),true) ifeq ($(HOST_OS),linux) - LOCAL_LDLIBS += -lrt -lpthread + LOCAL_LDLIBS += -lrt -lpthread -ldl endif endif diff --git a/flashlight/Android.mk b/flashlight/Android.mk index c696e1b..237d0df 100644 --- a/flashlight/Android.mk +++ b/flashlight/Android.mk @@ -1,4 +1,6 @@ # Copyright 2007 The Android Open Source Project LOCAL_SRC_FILES += flashlight/flashlight.c - +ifeq ($(QEMU_HARDWARE),yes) + LOCAL_CFLAGS += -DQEMU_FLASHLIGHT +endif diff --git a/flashlight/flashlight.c b/flashlight/flashlight.c index 028a1dc..a68a98e 100644 --- a/flashlight/flashlight.c +++ b/flashlight/flashlight.c @@ -4,10 +4,38 @@ #include <unistd.h> #include <fcntl.h> #include <errno.h> +#include "qemu.h" #define FLASHLIGHT "/sys/class/leds/spotlight/brightness" #define CAMERA_FLASH "/sys/class/timed_output/flash/enable" +#ifdef QEMU_HARDWARE +int qemu_get_flashlight_enabled() +{ + char question[256]; + char answer[256]; + int len; + + len = qemu_command_format( question, sizeof question, + "get_flashlight_enabled" ); + + len = qemu_control_query( question, len, answer, sizeof answer ); + if (len <= 0) return 0; + + /* we expect an answer of 0 or 1 */ + return (answer[0] == '1'); +} + +int qemu_set_flashlight_enabled(int on) +{ + return qemu_control_command( "set_flashlight_enabled:%d", on ); +} + +int qemu_enable_camera_flash(int milliseconds) +{ + return qemu_control_command( "enable_camera_flash:%d", milliseconds ); +} +#endif int get_flashlight_enabled() { @@ -15,6 +43,8 @@ int get_flashlight_enabled() int ret = 0; char value; + QEMU_FALLBACK(get_flashlight_enabled()); + fd = open(FLASHLIGHT, O_RDONLY); if(fd && read(fd, &value, 1) == 1) { ret = (value == '1'); @@ -29,6 +59,8 @@ int set_flashlight_enabled(int on) int nwr, ret, fd; char value[20]; + QEMU_FALLBACK(set_flashlight_enabled(on)); + fd = open(FLASHLIGHT, O_RDWR); if(fd < 0) return errno; @@ -46,6 +78,8 @@ int enable_camera_flash(int milliseconds) int nwr, ret, fd; char value[20]; + QEMU_FALLBACK(enable_camera_flash(milliseconds)); + fd = open(CAMERA_FLASH, O_RDWR); if(fd < 0) return errno; diff --git a/gps/Android.mk b/gps/Android.mk index 64ada57..6b33374 100644 --- a/gps/Android.mk +++ b/gps/Android.mk @@ -1,14 +1,13 @@ -# the Dream and Surf use the Qualcom GPS stuff +# Use hardware GPS implementation if available. # - ifneq ($(BOARD_GPS_LIBRARIES),) LOCAL_CFLAGS += -DHAVE_GPS_HARDWARE LOCAL_SHARED_LIBRARIES += $(BOARD_GPS_LIBRARIES) endif -# always compile the emulator-specific hardware for now +# Use emulator GPS implementation if QEMU_HARDWARE is set. # -USE_QEMU_GPS_HARDWARE := true +USE_QEMU_GPS_HARDWARE := $(QEMU_HARDWARE) ifeq ($(USE_QEMU_GPS_HARDWARE),true) LOCAL_CFLAGS += -DHAVE_QEMU_GPS_HARDWARE diff --git a/gps/gps.cpp b/gps/gps.cpp index efd1181..8b295af 100644 --- a/gps/gps.cpp +++ b/gps/gps.cpp @@ -3,6 +3,7 @@ #define LOG_TAG "libhardware" #include <utils/Log.h> +#include "qemu.h" static const GpsInterface* sGpsInterface = NULL; @@ -10,10 +11,7 @@ static void gps_find_hardware( void ) { #ifdef HAVE_QEMU_GPS_HARDWARE - char propBuf[PROPERTY_VALUE_MAX]; - - property_get("ro.kernel.qemu", propBuf, ""); - if (propBuf[0] == '1') { + if (qemu_check()) { sGpsInterface = gps_get_qemu_interface(); if (sGpsInterface) { LOGD("using QEMU GPS Hardware emulation\n"); diff --git a/gps/gps_qemu.c b/gps/gps_qemu.c index 67737c1..7296f22 100644 --- a/gps/gps_qemu.c +++ b/gps/gps_qemu.c @@ -1,7 +1,7 @@ #include <errno.h> #include <pthread.h> -#include <termios.h> +#include "qemu.h" #include <fcntl.h> #include <sys/epoll.h> #include <math.h> @@ -10,11 +10,10 @@ #define LOG_TAG "gps_qemu" #include <cutils/log.h> #include <cutils/sockets.h> -#include <cutils/properties.h> #include <hardware/gps.h> /* the name of the qemud-controlled socket */ -#define QEMUD_SOCKET_NAME "qemud_gps" +#define QEMU_CHANNEL_NAME "gps" #define GPS_DEBUG 0 @@ -549,7 +548,7 @@ typedef struct { GpsCallbacks callbacks; pthread_t thread; int control[2]; - + QemuChannel channel; } GpsState; static GpsState _gps_state[1]; @@ -739,68 +738,22 @@ Exit: static void gps_state_init( GpsState* state ) { - char prop[PROPERTY_VALUE_MAX]; - char device[256]; - int ret; - int done = 0; - state->init = 1; state->control[0] = -1; state->control[1] = -1; state->fd = -1; - // try to connect to the qemud socket - do { - state->fd = socket_local_client( QEMUD_SOCKET_NAME, - ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_STREAM ); - if (state->fd < 0) { - D("no '%s' control socket available: %s", QEMUD_SOCKET_NAME, strerror(errno)); - break; - } - snprintf( device, sizeof(device), "/dev/socket/%s", QEMUD_SOCKET_NAME ); - done = 1; - - } while (0); - - // otherwise, look for a kernel-provided device name - if (!done) do { - if (property_get("ro.kernel.android.gps",prop,"") == 0) { - D("no kernel-provided gps device name"); - break; - } - if ( snprintf(device, sizeof(device), "/dev/%s", prop) >= (int)sizeof(device) ) { - LOGE("gps serial device name too long: '%s'", prop); - break; - } - - do { - state->fd = open( device, O_RDWR ); - } while (state->fd < 0 && errno == EINTR); - - if (state->fd < 0) { - LOGE("could not open gps serial device %s: %s", device, strerror(errno) ); - break; - } - done = 1; - - } while (0); + state->fd = qemu_channel_open( &state->channel, + QEMU_CHANNEL_NAME, + O_RDONLY ); - if (!done) { + if (state->fd < 0) { D("no gps emulation detected"); return; } D("gps emulation will read from %s", device); - // disable echo on serial lines - if ( !memcmp( device, "/dev/ttyS", 9 ) ) { - struct termios ios; - tcgetattr( state->fd, &ios ); - ios.c_lflag = 0; /* disable ECHO, ICANON, etc... */ - tcsetattr( state->fd, TCSANOW, &ios ); - } - if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) { LOGE("could not create thread control socket pair: %s", strerror(errno)); goto Fail; @@ -893,7 +846,7 @@ qemu_gps_set_fix_frequency() if (!s->init) { D("%s: called with uninitialized state !!", __FUNCTION__); - return -1; + return; } D("%s: called", __FUNCTION__); diff --git a/hardware.c b/hardware.c new file mode 100644 index 0000000..bff4215 --- /dev/null +++ b/hardware.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <hardware/hardware.h> + +#include <cutils/properties.h> + +#include <dlfcn.h> +#include <string.h> +#include <pthread.h> +#include <errno.h> +#include <limits.h> + +#define LOG_TAG "HAL" +#include <utils/Log.h> + +/** Base path of the hal modules */ +#define HAL_LIBRARY_PATH "/system/lib/hw" + +/** + * There are a set of variant filename + * for modules. The form of the filename + * is "<MODULE_ID>.variant.so" so for the + * led module the Dream variants of base are + * "ro.product.board" and "ro.arch" would be: + * + * led.trout.so + * led.ARMV6.so + * led.default.so + */ +#define HAL_DEFAULT_VARIANT "default" +#define HAL_VARIANT_KEYS_COUNT 3 +static const char *variant_keys[HAL_VARIANT_KEYS_COUNT] = { + "ro.product.board", + "ro.arch", + HAL_DEFAULT_VARIANT +}; + +/** + * Load the file defined by the path and if succesfull + * return the dlopen handle and the hmi. + * @return 0 = success, !0 = failure. + */ +static int load(const char *id, + const char *path, + void **pHandle, + const struct hw_module_t **pHmi) +{ + int status; + void *handle; + const struct hw_module_t *hmi; + + LOGV("load: E id=%s path=%s", id, path); + + /* + * load the symbols resolving undefined symbols before + * dlopen returns. Since RTLD_GLOBAL is not or'd in with + * RTLD_NOW the external symbols will not be global + */ + handle = dlopen(path, RTLD_NOW); + if (handle == NULL) { + char const *err_str = dlerror(); + LOGE("load: module=%s error=%s", path, err_str); + status = -EINVAL; + goto done; + } + + /* Get the address of the struct hal_module_info. */ + const char *sym = HAL_MODULE_INFO_SYM_AS_STR; + hmi = (const struct hw_module_t *)dlsym(handle, sym); + if (hmi == NULL) { + char const *err_str = dlerror(); + LOGE("load: couldn't find symbol %s", sym); + status = -EINVAL; + goto done; + } + + /* Check that the id matches */ + if (strcmp(id, hmi->id) != 0) { + LOGE("load: id=%s != hmi->id=%s", id, hmi->id); + status = -EINVAL; + goto done; + } + + /* success */ + status = 0; + +done: + if (status != 0) { + hmi = NULL; + if (handle != NULL) { + dlclose(handle); + handle = NULL; + } + } + + *pHmi = hmi; + *pHandle = handle; + + LOGV("load: X id=%s path=%s hmi=%p pHandle=%p status=%d", + id, path, *pHmi, *pHandle, status); + return status; +} + +int hw_get_module(const char *id, const struct hw_module_t **module) +{ + int status; + const struct hw_module_t *hmi = NULL; + char path[PATH_MAX]; + char variant[PATH_MAX]; + void *handle = NULL; + int i; + + /* + * Here we rely on the fact that calling dlopen multiple times on + * the same .so will simply increment a refcount (and not load + * a new copy of the library). + * We also assume that dlopen() is thread-safe. + */ + + LOGV("hal_module_info_get: Load module id=%s", id); + + /* Loop through the configuration variants looking for a module */ + status = -EINVAL; + for (i = 0; (status != 0) && (i < HAL_VARIANT_KEYS_COUNT); i++) { + + /* Get variant or default */ + if (strcmp(variant_keys[i], HAL_DEFAULT_VARIANT) == 0) { + strncpy(variant, HAL_DEFAULT_VARIANT, sizeof(variant)-1); + variant[sizeof(variant)-1] = 0; + } else { + if (property_get(variant_keys[i], variant, NULL) == 0) { + continue; + } + } + + /* Construct the path then try to load */ + snprintf(path, sizeof(path), "%s/%s.%s.so", + HAL_LIBRARY_PATH, id, variant); + status = load(id, path, &handle, &hmi); + } + if (status != 0) { + hmi = NULL; + if (handle != NULL) { + dlclose(handle); + } + } + + *module = hmi; + LOGV("hal_module_info_get: X id=%s hmi=%p status=%d", id, hmi, status); + + return status; +} diff --git a/include/hardware/AudioHardwareBase.h b/include/hardware/AudioHardwareBase.h new file mode 100644 index 0000000..1c83d70 --- /dev/null +++ b/include/hardware/AudioHardwareBase.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AUDIO_HARDWARE_BASE_H +#define ANDROID_AUDIO_HARDWARE_BASE_H + +#include "hardware/AudioHardwareInterface.h" + + +namespace android { + +// ---------------------------------------------------------------------------- + +/** + * AudioHardwareBase is a convenient base class used for implementing the + * AudioHardwareInterface interface. + */ +class AudioHardwareBase : public AudioHardwareInterface +{ +public: + AudioHardwareBase(); + virtual ~AudioHardwareBase() { } + + /** + * Audio routing methods. Routes defined in include/hardware/AudioSystem.h. + * Audio routes can be (ROUTE_EARPIECE | ROUTE_SPEAKER | ROUTE_BLUETOOTH + * | ROUTE_HEADSET) + * + * setRouting sets the routes for a mode. This is called at startup. It is + * also called when a new device is connected, such as a wired headset is + * plugged in or a Bluetooth headset is paired. + */ + virtual status_t setRouting(int mode, uint32_t routes); + + virtual status_t getRouting(int mode, uint32_t* routes); + + /** + * setMode is called when the audio mode changes. NORMAL mode is for + * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL + * when a call is in progress. + */ + virtual status_t setMode(int mode); + virtual status_t getMode(int* mode); + + // Temporary interface, do not use + // TODO: Replace with a more generic key:value get/set mechanism + virtual status_t setParameter(const char* key, const char* value); + + virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount); + + /**This method dumps the state of the audio hardware */ + virtual status_t dumpState(int fd, const Vector<String16>& args); + +protected: + int mMode; + uint32_t mRoutes[AudioSystem::NUM_MODES]; +}; + +}; // namespace android + +#endif // ANDROID_AUDIO_HARDWARE_BASE_H diff --git a/include/hardware/AudioHardwareInterface.h b/include/hardware/AudioHardwareInterface.h index febc86a..66cf0ff 100644 --- a/include/hardware/AudioHardwareInterface.h +++ b/include/hardware/AudioHardwareInterface.h @@ -33,137 +33,159 @@ namespace android { // ---------------------------------------------------------------------------- /** - * This is the abstraction interface for the audio output hardware. It provides - * information about various properties of the audio output hardware driver. + * AudioStreamOut is the abstraction interface for the audio output hardware. + * + * It provides information about various properties of the audio output hardware driver. */ class AudioStreamOut { public: virtual ~AudioStreamOut() = 0; - + /** return audio sampling rate in hz - eg. 44100 */ virtual uint32_t sampleRate() const = 0; - + /** returns size of output buffer - eg. 4800 */ virtual size_t bufferSize() const = 0; - - /** - * return number of output audio channels. - * Acceptable values are 1 (mono) or 2 (stereo) + + /** + * return number of output audio channels. + * Acceptable values are 1 (mono) or 2 (stereo) */ virtual int channelCount() const = 0; - + /** - * return audio format in 8bit or 16bit PCM format - - * eg. AudioSystem:PCM_16_BIT + * return audio format in 8bit or 16bit PCM format - + * eg. AudioSystem:PCM_16_BIT */ virtual int format() const = 0; - - /** - * This method can be used in situations where audio mixing is done in the - * hardware. It is a direct interface to the hardware to set the volume as - * as opposed to controlling this via the framework. It could be multiple - * PCM outputs or hardware accelerated codecs such as MP3 or AAC + + /** + * return the frame size (number of bytes per sample). + */ + uint32_t frameSize() const { return channelCount()*((format()==AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(int8_t)); } + + /** + * return the audio hardware driver latency in milli seconds. + */ + virtual uint32_t latency() const = 0; + + /** + * Use this method in situations where audio mixing is done in the + * hardware. This method serves as a direct interface with hardware, + * allowing you to directly set the volume as apposed to via the framework. + * This method might produce multiple PCM outputs or hardware accelerated + * codecs, such as MP3 or AAC. */ virtual status_t setVolume(float volume) = 0; - + /** write audio buffer to driver. Returns number of bytes written */ virtual ssize_t write(const void* buffer, size_t bytes) = 0; /** dump the state of the audio output device */ - virtual status_t dump(int fd, const Vector<String16>& args) = 0; + virtual status_t dump(int fd, const Vector<String16>& args) = 0; }; /** - * This is the abstraction interface for the audio input hardware. It defines - * the various properties of the audio hardware input driver. + * AudioStreamIn is the abstraction interface for the audio input hardware. + * + * It defines the various properties of the audio hardware input driver. */ class AudioStreamIn { public: virtual ~AudioStreamIn() = 0; - + /** return the input buffer size allowed by audio driver */ virtual size_t bufferSize() const = 0; /** return the number of audio input channels */ virtual int channelCount() const = 0; - - /** - * return audio format in 8bit or 16bit PCM format - - * eg. AudioSystem:PCM_16_BIT + + /** + * return audio format in 8bit or 16bit PCM format - + * eg. AudioSystem:PCM_16_BIT */ virtual int format() const = 0; + /** + * return the frame size (number of bytes per sample). + */ + uint32_t frameSize() const { return channelCount()*((format()==AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(int8_t)); } + /** set the input gain for the audio driver. This method is for * for future use */ virtual status_t setGain(float gain) = 0; - + /** read audio buffer in from audio driver */ virtual ssize_t read(void* buffer, ssize_t bytes) = 0; /** dump the state of the audio input device */ virtual status_t dump(int fd, const Vector<String16>& args) = 0; + + /** + * Put the audio hardware input into standby mode. Returns + * status based on include/utils/Errors.h + */ + virtual status_t standby() = 0; + }; -/** - * This defines the interface to the audio hardware abstraction layer. It - * supports setting and getting parameters, selecting audio routing paths and - * defining input and output streams. - * - * AudioFlinger initializes the audio hardware and immediately opens an output - * stream. Audio routing can be set to output to handset, speaker, bluetooth or - * headset. +/** + * AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer. + * + * The interface supports setting and getting parameters, selecting audio routing + * paths, and defining input and output streams. + * + * AudioFlinger initializes the audio hardware and immediately opens an output stream. + * You can set Audio routing to output to handset, speaker, Bluetooth, or a headset. * - * The audio input stream is initialized when AudioFlinger is called to carry - * out a record operation. + * The audio input stream is initialized when AudioFlinger is called to carry out + * a record operation. */ class AudioHardwareInterface { public: - AudioHardwareInterface(); - virtual ~AudioHardwareInterface() { } - - /** - * check to see if the audio hardware interface has been initialized. - * return status based on values defined in include/utils/Errors.h + /** + * check to see if the audio hardware interface has been initialized. + * return status based on values defined in include/utils/Errors.h */ virtual status_t initCheck() = 0; - /** - * put the audio hardware into standby mode to conserve power. Returns - * status based on include/utils/Errors.h + /** + * put the audio hardware into standby mode to conserve power. Returns + * status based on include/utils/Errors.h */ virtual status_t standby() = 0; /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */ virtual status_t setVoiceVolume(float volume) = 0; - - /** - * set the audio volume for all audio activities other than voice call. - * Range between 0.0 and 1.0. IF any value other than NO_ERROR is returned, + + /** + * set the audio volume for all audio activities other than voice call. + * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned, * the software mixer will emulate this capability. */ virtual status_t setMasterVolume(float volume) = 0; - /** - * Audio routing methods. Routes defined in include/hardware/AudioSystem.h. - * Audio routes can be (ROUTE_EARPIECE | ROUTE_SPEAKER | ROUTE_BLUETOOTH + /** + * Audio routing methods. Routes defined in include/hardware/AudioSystem.h. + * Audio routes can be (ROUTE_EARPIECE | ROUTE_SPEAKER | ROUTE_BLUETOOTH * | ROUTE_HEADSET) - * + * * setRouting sets the routes for a mode. This is called at startup. It is - * also called when a new device is connected, such as a wired headset is - * plugged in or a Bluetooth headset is paired + * also called when a new device is connected, such as a wired headset is + * plugged in or a Bluetooth headset is paired. */ - virtual status_t setRouting(int mode, uint32_t routes); - - virtual status_t getRouting(int mode, uint32_t* routes); - + virtual status_t setRouting(int mode, uint32_t routes) = 0; + + virtual status_t getRouting(int mode, uint32_t* routes) = 0; + /** * setMode is called when the audio mode changes. NORMAL mode is for - * standard audio playback, RINGTONE when a ringtone is playing and IN_CALL + * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL * when a call is in progress. */ - virtual status_t setMode(int mode); - virtual status_t getMode(int* mode); + virtual status_t setMode(int mode) = 0; + virtual status_t getMode(int* mode) = 0; // mic mute virtual status_t setMicMute(bool state) = 0; @@ -171,38 +193,41 @@ public: // Temporary interface, do not use // TODO: Replace with a more generic key:value get/set mechanism - virtual status_t setParameter(const char* key, const char* value); + virtual status_t setParameter(const char* key, const char* value) = 0; + // Returns audio input buffer size according to parameters passed or 0 if one of the + // parameters is not supported + virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0; + /** This method creates and opens the audio hardware output stream */ virtual AudioStreamOut* openOutputStream( int format=0, int channelCount=0, - uint32_t sampleRate=0) = 0; + uint32_t sampleRate=0, + status_t *status=0) = 0; /** This method creates and opens the audio hardware input stream */ virtual AudioStreamIn* openInputStream( int format, int channelCount, - uint32_t sampleRate) = 0; - + uint32_t sampleRate, + status_t *status) = 0; + /**This method dumps the state of the audio hardware */ - virtual status_t dumpState(int fd, const Vector<String16>& args); + virtual status_t dumpState(int fd, const Vector<String16>& args) = 0; static AudioHardwareInterface* create(); protected: /** - * doRouting actually initiates the routing to occur. A call to setRouting - * or setMode may result in a routing change. The generic logic will call + * doRouting actually initiates the routing. A call to setRouting + * or setMode may result in a routing change. The generic logic calls * doRouting when required. If the device has any special requirements these * methods can be overriden. */ virtual status_t doRouting() = 0; - - virtual status_t dump(int fd, const Vector<String16>& args) = 0; - int mMode; - uint32_t mRoutes[AudioSystem::NUM_MODES]; + virtual status_t dump(int fd, const Vector<String16>& args) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/hardware/copybit.h b/include/hardware/copybit.h new file mode 100644 index 0000000..3c873e0 --- /dev/null +++ b/include/hardware/copybit.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_COPYBIT_INTERFACE_H +#define ANDROID_COPYBIT_INTERFACE_H + +#include <hardware/hardware.h> + +#include <stdint.h> +#include <sys/cdefs.h> +#include <sys/types.h> + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define COPYBIT_HARDWARE_MODULE_ID "copybit" + +/** + * Name of the graphics device to open + */ +#define COPYBIT_HARDWARE_COPYBIT0 "copybit0" + +/* supported pixel-formats. these must be compatible with + * graphics/PixelFormat.java, ui/PixelFormat.h, pixelflinger/format.h + */ +enum { + COPYBIT_FORMAT_RGBA_8888 = 1, + COPYBIT_FORMAT_RGB_565 = 4, + COPYBIT_FORMAT_BGRA_8888 = 5, + COPYBIT_FORMAT_RGBA_5551 = 6, + COPYBIT_FORMAT_RGBA_4444 = 7, + COPYBIT_FORMAT_YCbCr_422_SP = 0x10, + COPYBIT_FORMAT_YCbCr_420_SP = 0x11 +}; + +/* name for copybit_set_parameter */ +enum { + /* rotation of the source image in degrees (0 to 359) */ + COPYBIT_ROTATION_DEG = 1, + /* plane alpha value */ + COPYBIT_PLANE_ALPHA = 2, + /* enable or disable dithering */ + COPYBIT_DITHER = 3, + /* transformation applied (this is a superset of COPYBIT_ROTATION_DEG) */ + COPYBIT_TRANSFORM = 4, +}; + +/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */ +enum { + /* flip source image horizontally */ + COPYBIT_TRANSFORM_FLIP_H = 0x01, + /* flip source image vertically */ + COPYBIT_TRANSFORM_FLIP_V = 0x02, + /* rotate source image 90 degres */ + COPYBIT_TRANSFORM_ROT_90 = 0x04, + /* rotate source image 180 degres */ + COPYBIT_TRANSFORM_ROT_180 = 0x03, + /* rotate source image 270 degres */ + COPYBIT_TRANSFORM_ROT_270 = 0x07, +}; + +/* enable/disable value copybit_set_parameter */ +enum { + COPYBIT_DISABLE = 0, + COPYBIT_ENABLE = 1 +}; + +/* use get_static_info() to query static informations about the hardware */ +enum { + /* Maximum amount of minification supported by the hardware*/ + COPYBIT_MINIFICATION_LIMIT = 1, + /* Maximum amount of magnification supported by the hardware */ + COPYBIT_MAGNIFICATION_LIMIT = 2, + /* Number of fractional bits support by the scaling engine */ + COPYBIT_SCALING_FRAC_BITS = 3, + /* Supported rotation step in degres. */ + COPYBIT_ROTATION_STEP_DEG = 4, +}; + +/* Image structure */ +struct copybit_image_t { + /* width */ + uint32_t w; + /* height */ + uint32_t h; + /* format COPYBIT_FORMAT_xxx */ + int32_t format; + /* offset from base to first pixel */ + uint32_t offset; + /* base of buffer with image */ + void *base; + /* file descriptor for image */ + int fd; +}; + +/* Rectangle */ +struct copybit_rect_t { + /* left */ + int l; + /* top */ + int t; + /* right */ + int r; + /* bottom */ + int b; +}; + +/* Region */ +struct copybit_region_t { + int (*next)(struct copybit_region_t const *region, struct copybit_rect_t *rect); +}; + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct copybit_module_t { + struct hw_module_t common; +}; + +/** + * Every device data structure must begin with hw_device_t + * followed by module specific public methods and attributes. + */ +struct copybit_device_t { + struct hw_device_t common; + + /** + * Set a copybit parameter. + * + * @param dev from open + * @param name one for the COPYBIT_NAME_xxx + * @param value one of the COPYBIT_VALUE_xxx + * + * @return 0 if successful + */ + int (*set_parameter)(struct copybit_device_t *dev, int name, int value); + + /** + * Get a static copybit information. + * + * @param dev from open + * @param name one of the COPYBIT_STATIC_xxx + * + * @return value or -EINVAL if error + */ + int (*get)(struct copybit_device_t *dev, int name); + + /** + * Execute the bit blit copy operation + * + * @param dev from open + * @param dst is the destination image + * @param src is the source image + * @param region the clip region + * + * @return 0 if successful + */ + int (*blit)(struct copybit_device_t *dev, + struct copybit_image_t const *dst, + struct copybit_image_t const *src, + struct copybit_region_t const *region); + + /** + * Execute the stretch bit blit copy operation + * + * @param dev from open + * @param dst is the destination image + * @param src is the source image + * @param dst_rect is the destination rectangle + * @param src_rect is the source rectangle + * @param region the clip region + * + * @return 0 if successful + */ + int (*stretch)(struct copybit_device_t *dev, + struct copybit_image_t const *dst, + struct copybit_image_t const *src, + struct copybit_rect_t const *dst_rect, + struct copybit_rect_t const *src_rect, + struct copybit_region_t const *region); +}; + + +/** convenience API for opening and closing a device */ + +static inline int copybit_open(const struct hw_module_t* module, + struct copybit_device_t** device) { + return module->methods->open(module, + COPYBIT_HARDWARE_COPYBIT0, (struct hw_device_t**)device); +} + +static inline int copybit_close(struct copybit_device_t* device) { + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_COPYBIT_INTERFACE_H diff --git a/include/hardware/gps.h b/include/hardware/gps.h index 54b50a5..5f8740f 100644 --- a/include/hardware/gps.h +++ b/include/hardware/gps.h @@ -23,36 +23,58 @@ extern "C" { #endif -/** milliseconds since January 1, 1970 */ +/** Milliseconds since January 1, 1970 */ typedef int64_t GpsUtcTime; -/** maximum number of Space Vehicles for gps_sv_status_callback */ +/** Maximum number of SVs for gps_sv_status_callback(). */ #define GPS_MAX_SVS 32 - +/** Requested mode for GPS operation. */ typedef uint16_t GpsPositionMode; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** Mode for running GPS standalone (no assistance). */ #define GPS_POSITION_MODE_STANDALONE 0 +/** SUPL MS-Based mode. */ #define GPS_POSITION_MODE_MS_BASED 1 +/** SUPL MS-Assisted mode. */ #define GPS_POSITION_MODE_MS_ASSISTED 2 +/** GPS status event values. */ typedef uint16_t GpsStatusValue; -// IMPORTANT - these symbols here must match constants in GpsLocationProvider.java +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** GPS status unknown. */ #define GPS_STATUS_NONE 0 +/** GPS has begun navigating. */ #define GPS_STATUS_SESSION_BEGIN 1 +/** GPS has stopped navigating. */ #define GPS_STATUS_SESSION_END 2 +/** GPS has powered on but is not navigating. */ #define GPS_STATUS_ENGINE_ON 3 +/** GPS is powered off. */ #define GPS_STATUS_ENGINE_OFF 4 +/** Flags to indicate which values are valid in a GpsLocation. */ typedef uint16_t GpsLocationFlags; -// IMPORTANT - these symbols here must match constants in GpsLocationProvider.java +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** GpsLocation has valid latitude and longitude. */ #define GPS_LOCATION_HAS_LAT_LONG 0x0001 +/** GpsLocation has valid altitude. */ #define GPS_LOCATION_HAS_ALTITUDE 0x0002 +/** GpsLocation has valid speed. */ #define GPS_LOCATION_HAS_SPEED 0x0004 +/** GpsLocation has valid bearing. */ #define GPS_LOCATION_HAS_BEARING 0x0008 +/** GpsLocation has valid accuracy. */ #define GPS_LOCATION_HAS_ACCURACY 0x0010 +/** Flags used to specify which aiding data to delete + when calling delete_aiding_data(). */ typedef uint16_t GpsAidingData; -// IMPORTANT - these symbols here must match constants in GpsLocationProvider.java +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. #define GPS_DELETE_EPHEMERIS 0x0001 #define GPS_DELETE_ALMANAC 0x0002 #define GPS_DELETE_POSITION 0x0004 @@ -68,73 +90,88 @@ typedef uint16_t GpsAidingData; #define GPS_DELETE_ALL 0xFFFF /** - * names for GPS XTRA interface + * Name for the GPS XTRA interface. */ #define GPS_XTRA_INTERFACE "gps-xtra" /** - * names for GPS supplemental interface - * TODO: Remove not used. + * Name for the GPS SUPL interface. */ #define GPS_SUPL_INTERFACE "gps-supl" -/** The location */ +/** Represents a location. */ typedef struct { - /** contains GpsLocationFlags bits */ + /** Contains GpsLocationFlags bits. */ uint16_t flags; + /** Represents latitude in degrees. */ double latitude; + /** Represents longitude in degrees. */ double longitude; + /** Represents altitude in meters above the WGS 84 reference + * ellipsoid. */ double altitude; + /** Represents speed in meters per second. */ float speed; + /** Represents heading in degrees. */ float bearing; + /** Represents expected accuracy in meters. */ float accuracy; + /** Timestamp for the location fix. */ GpsUtcTime timestamp; } GpsLocation; -/** The status */ +/** Represents the status. */ typedef struct { GpsStatusValue status; } GpsStatus; -/** Space Vehicle info */ +/** Represents SV information. */ typedef struct { + /** Pseudo-random number for the SV. */ int prn; + /** Signal to noise ratio. */ float snr; + /** Elevation of SV in degrees. */ float elevation; + /** Azimuth of SV in degrees. */ float azimuth; } GpsSvInfo; -/** Space Vehicle status */ +/** Represents SV status. */ typedef struct { - /** number of SVs currently visible */ + /** Number of SVs currently visible. */ int num_svs; - /** Array of space vehicle info */ + /** Contains an array of SV information. */ GpsSvInfo sv_list[GPS_MAX_SVS]; - /** bit mask indicating which SVs have ephemeris data */ + /** Represents a bit mask indicating which SVs + * have ephemeris data. + */ uint32_t ephemeris_mask; - /** bit mask indicating which SVs have almanac data */ + /** Represents a bit mask indicating which SVs + * have almanac data. + */ uint32_t almanac_mask; /** - * bit mask indicating which SVs were used for - * computing the most recent position fix + * Represents a bit mask indicating which SVs + * were used for computing the most recent position fix. */ uint32_t used_in_fix_mask; } GpsSvStatus; -/** Callback with location information */ +/** Callback with location information. */ typedef void (* gps_location_callback)(GpsLocation* location); -/** Callback with the status information */ +/** Callback with status information. */ typedef void (* gps_status_callback)(GpsStatus* status); -/** Callback with the space vehicle status information */ +/** Callback with SV status information. */ typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info); -/** GPS call back structure */ +/** GPS callback structure. */ typedef struct { gps_location_callback location_cb; gps_status_callback status_cb; @@ -142,40 +179,40 @@ typedef struct { } GpsCallbacks; -/** Standard GPS interface */ +/** Represents the standard GPS interface. */ typedef struct { /** - * Open the interface and provide the callback routines + * Opens the interface and provides the callback routines * to the implemenation of this interface. */ int (*init)( GpsCallbacks* callbacks ); - /** Start navigating */ + /** Starts navigating. */ int (*start)( void ); - /** Stop navigating */ + /** Stops navigating. */ int (*stop)( void ); - /** Set requested frequency of fixes in seconds */ + /** Sets requested frequency of fixes in seconds. */ void (*set_fix_frequency)( int frequency ); - /** Close the interface */ + /** Closes the interface. */ void (*cleanup)( void ); - /** Inject the current time */ + /** Injects the current time. */ int (*inject_time)(GpsUtcTime time, int64_t timeReference, int uncertainty); /** - * The next call to start will not use the information - * defined in the flags. GPS_DELETE_ALL is passed for + * Specifies that the next call to start will not use the + * information defined in the flags. GPS_DELETE_ALL is passed for * a cold start. */ void (*delete_aiding_data)(GpsAidingData flags); /** - * fix_frequency is time between fixes in seconds. - * set fix_frequency to zero for a single shot fix. + * fix_frequency represents the time between fixes in seconds. + * Set fix_frequency to zero for a single-shot fix. */ int (*set_position_mode)(GpsPositionMode mode, int fix_frequency); @@ -183,31 +220,37 @@ typedef struct { const void* (*get_extension)(const char* name); } GpsInterface; -/** The download request callback routine. */ +/** Callback to request the client to download XTRA data. + The client should download XTRA data and inject it by calling + inject_xtra_data(). */ typedef void (* gps_xtra_download_request)(); -/** The download request callback structure. */ +/** Callback structure for the XTRA interface. */ typedef struct { gps_xtra_download_request download_request_cb; } GpsXtraCallbacks; /** Extended interface for XTRA support. */ typedef struct { + /** + * Opens the XTRA interface and provides the callback routines + * to the implemenation of this interface. + */ int (*init)( GpsXtraCallbacks* callbacks ); + /** Injects XTRA data into the GPS. */ int (*inject_xtra_data)( char* data, int length ); } GpsXtraInterface; -/** returns the hardware GPS interface. */ +/** Returns the hardware GPS interface. */ const GpsInterface* gps_get_hardware_interface(); /** - * returns the qemu hardware interface GPS interface. + * Returns the qemu emulated GPS interface. */ const GpsInterface* gps_get_qemu_interface(); /** - * returns the default GPS interface, - * implemented in lib/hardware/gps.cpp. + * Returns the default GPS interface. */ const GpsInterface* gps_get_interface(); diff --git a/include/hardware/hardware.h b/include/hardware/hardware.h new file mode 100644 index 0000000..65ce8d0 --- /dev/null +++ b/include/hardware/hardware.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_HARDWARE_H +#define ANDROID_INCLUDE_HARDWARE_HARDWARE_H + +#include <stdint.h> +#include <sys/cdefs.h> + +__BEGIN_DECLS + +/* + * Value for the hw_module_t.tag field + */ +#define HARDWARE_MODULE_TAG 'HWMT' +#define HARDWARE_DEVICE_TAG 'HWDT' + +struct hw_module_t; +struct hw_module_methods_t; +struct hw_device_t; + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct hw_module_t { + /** tag must be initialized to HARDWARE_MODULE_TAG */ + uint32_t tag; + + /** major version number for the module */ + uint16_t version_major; + + /** minor version number of the module */ + uint16_t version_minor; + + /** Identifier of module */ + const char *id; + + /** Name of this module */ + const char *name; + + /** Author/owner/implementor of the module */ + const char *author; + + /** Modules methods */ + struct hw_module_methods_t* methods; + + /** padding to 128 bytes, reserved for future use */ + uint32_t reserved[32-6]; +}; + +struct hw_module_methods_t { + /** Open a specific device */ + int (*open)(const struct hw_module_t* module, const char* id, + struct hw_device_t** device); +}; + +/** + * Every device data structure must begin with hw_device_t + * followed by module specific public methods and attributes. + */ +struct hw_device_t { + /** tag must be initialized to HARDWARE_DEVICE_TAG */ + uint32_t tag; + + /** version number for hw_device_t */ + uint32_t version; + + /** reference to the module this device belongs to */ + struct hw_module_t* module; + + /** padding reserved for future use */ + uint32_t reserved[12]; + + /** Close this device */ + int (*close)(struct hw_device_t* device); +}; + +/** + * Name of the hal_module_info + */ +#define HAL_MODULE_INFO_SYM HMI + +/** + * Name of the hal_module_info as a string + */ +#define HAL_MODULE_INFO_SYM_AS_STR "HMI" + +/** + * Get the module info associated with a module by id. + * @return: 0 == success, <0 == error and *pHmi == NULL + */ +int hw_get_module(const char *id, const struct hw_module_t **module); + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */ diff --git a/include/hardware/led.h b/include/hardware/led.h index d7b2363..b5acb73 100644 --- a/include/hardware/led.h +++ b/include/hardware/led.h @@ -22,15 +22,16 @@ extern "C" { #endif /** - * Change the state of the led + * Changes the state of the LED. * - * To turn on the led; Alpha != 0 and RBG != 0, onMS == 0 && offMS == 0. - * To blink the led; Alpha != 0 and RBG != 0, onMS != 0 && offMS != 0. - * To turn off the led; Alpha == 0 or RGB == 0. + * -# Turn on LED: Alpha != 0 and RBG != 0, onMS == 0 && offMS == 0. + * -# Blink LED: Alpha != 0 and RBG != 0, onMS != 0 && offMS != 0. + * -# Turn off LED: Alpha == 0 or RGB == 0. * - * @param colorARGB the is color, Alpha=31:24, Red=23:16 Green=15:8 Blue=7:0 - * @param onMS is the time on in milli-seconds - * @param offMS is the time off in milli-seconds + * @param colorARGB represents the LED's color: Alpha=31:24, Red=23:16 + * Green=15:8 Blue=7:0 + * @param onMS represents the time the LED is on in milliseconds + * @param offMS represents the time the LED is off in milliseconds * * @return 0 if successful */ diff --git a/include/hardware/overlay.h b/include/hardware/overlay.h new file mode 100644 index 0000000..b798c56 --- /dev/null +++ b/include/hardware/overlay.h @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_OVERLAY_INTERFACE_H +#define ANDROID_OVERLAY_INTERFACE_H + +#include <hardware/hardware.h> + +#include <stdint.h> +#include <sys/cdefs.h> +#include <sys/types.h> + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define OVERLAY_HARDWARE_MODULE_ID "overlay" + +/** + * Name of the overlay device to open + */ +#define OVERLAY_HARDWARE_OVERLAY0 "overlay0" + +/*****************************************************************************/ + +/* possible overlay formats */ +enum { + OVERLAY_FORMAT_RGBA_8888 = 1, + OVERLAY_FORMAT_RGB_565 = 4, + OVERLAY_FORMAT_BGRA_8888 = 5, + OVERLAY_FORMAT_YCbCr_422_SP = 0x10, + OVERLAY_FORMAT_YCbCr_420_SP = 0x11, + OVERLAY_FORMAT_YCbCr_422_P = 0x14, + OVERLAY_FORMAT_YCbCr_420_P = 0x15 +}; + +/* values for rotation */ +enum { + /* flip source image horizontally */ + OVERLAY_TRANSFORM_FLIP_H = 0x01, + /* flip source image vertically */ + OVERLAY_TRANSFORM_FLIP_V = 0x02, + /* rotate source image 90 degrees */ + OVERLAY_TRANSFORM_ROT_90 = 0x04, + /* rotate source image 180 degrees */ + OVERLAY_TRANSFORM_ROT_180 = 0x03, + /* rotate source image 270 degrees */ + OVERLAY_TRANSFORM_ROT_270 = 0x07, +}; + +/* names for setParameter() */ +enum { + OVERLAY_ROTATION_DEG = 1, + OVERLAY_DITHER = 3, +}; + +/* enable/disable value setParameter() */ +enum { + OVERLAY_DISABLE = 0, + OVERLAY_ENABLE = 1 +}; + +/* names for get() */ +enum { + /* Maximum amount of minification supported by the hardware*/ + OVERLAY_MINIFICATION_LIMIT = 1, + /* Maximum amount of magnification supported by the hardware */ + OVERLAY_MAGNIFICATION_LIMIT = 2, + /* Number of fractional bits support by the overlay scaling engine */ + OVERLAY_SCALING_FRAC_BITS = 3, + /* Supported rotation step in degrees. */ + OVERLAY_ROTATION_STEP_DEG = 4, + /* horizontal alignment in pixels */ + OVERLAY_HORIZONTAL_ALIGNMENT = 5, + /* vertical alignment in pixels */ + OVERLAY_VERTICAL_ALIGNMENT = 6, + /* width alignment restrictions. negative number for max. power-of-two */ + OVERLAY_WIDTH_ALIGNMENT = 7, + /* height alignment restrictions. negative number for max. power-of-two */ + OVERLAY_HEIGHT_ALIGNMENT = 8, +}; + +/*****************************************************************************/ + +/* opaque reference to an Overlay kernel object */ +typedef struct { + int numFds; + int fds[4]; + int numInts; + int data[0]; +} overlay_handle_t; + +typedef struct overlay_t { + uint32_t w; + uint32_t h; + int32_t format; + uint32_t w_stride; + uint32_t h_stride; + uint32_t reserved[3]; + /* returns a reference to this overlay's handle (the caller doesn't + * take ownership) */ + overlay_handle_t const* (*getHandleRef)(struct overlay_t* overlay); + uint32_t reserved_procs[7]; +} overlay_t; + +/*****************************************************************************/ + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct overlay_module_t { + struct hw_module_t common; +}; + +/*****************************************************************************/ + +/** + * Every device data structure must begin with hw_device_t + * followed by module specific public methods and attributes. + */ +struct overlay_device_t { + struct hw_device_t common; + + /* get static informations about the capabilities of the overlay engine */ + int (*get)(struct overlay_device_t *dev, int name); + + /* creates an overlay matching the given parameters as closely as possible. + * returns an error if no more overlays are available. The actual + * size and format is returned in overlay_t. */ + overlay_t* (*createOverlay)(struct overlay_device_t *dev, + uint32_t w, uint32_t h, int32_t format); + + /* destroys an overlay. This call releases all + * resources associated with overlay_t and make it invalid */ + void (*destroyOverlay)(struct overlay_device_t *dev, + overlay_t* overlay); + + /* set position and scaling of the given overlay as closely as possible. + * if scaling cannot be performed, overlay must be centered. */ + int (*setPosition)(struct overlay_device_t *dev, + overlay_t* overlay, + int x, int y, uint32_t w, uint32_t h); + + /* returns the actual position and size of the overlay */ + int (*getPosition)(struct overlay_device_t *dev, + overlay_t* overlay, + int* x, int* y, uint32_t* w, uint32_t* h); + + /* sets configurable parameters for this overlay. returns an error if not + * supported. */ + int (*setParameter)(struct overlay_device_t *dev, + overlay_t* overlay, int param, int value); + + /* swaps overlay buffers for double-buffered overlay. the actual swap is + * synchronized with VSYNC. Typically, this function blocks until a new + * buffer is available. */ + int (*swapBuffers)(struct overlay_device_t *dev, + overlay_t* overlay); + + /* returns the offset in bytes of the current available buffer. When this + * function returns, the buffer is ready to be used immediately. Typically, + * this function blocks until a buffer is available. */ + int (*getOffset)(struct overlay_device_t *dev, + overlay_t* overlay); + + /* returns a filedescriptor that can be used to mmap() the overlay's + * memory. If this feature is not supported, an error is returned. */ + int (*getMemory)(struct overlay_device_t *dev); +}; + +/*****************************************************************************/ + +/** convenience API for opening and closing a device */ + +static inline int overlay_open(const struct hw_module_t* module, + struct overlay_device_t** device) { + return module->methods->open(module, + OVERLAY_HARDWARE_OVERLAY0, (struct hw_device_t**)device); +} + +static inline int overlay_close(struct overlay_device_t* device) { + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_OVERLAY_INTERFACE_H diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h index 19fd72c..a7ab7ad 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -14,29 +14,47 @@ * limitations under the License. */ -#ifndef _HARDWARE_SENSORS_H -#define _HARDWARE_SENSORS_H +#ifndef ANDROID_SENSORS_INTERFACE_H +#define ANDROID_SENSORS_INTERFACE_H #include <stdint.h> +#include <sys/cdefs.h> +#include <sys/types.h> -#if __cplusplus -extern "C" { -#endif +#include <hardware/hardware.h> + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define SENSORS_HARDWARE_MODULE_ID "sensors" + +/** + * Name of the sensors device to open + */ +#define SENSORS_HARDWARE_CONTROL "control" +#define SENSORS_HARDWARE_DATA "data" /** - * Sensor IDs must be a power of two and - * must match values in SensorManager.java + * Handles must be higher than SENSORS_HANDLE_BASE */ +#define SENSORS_HANDLE_BASE 0 +#define SENSORS_HANDLE_BITS 8 +#define SENSORS_HANDLE_COUNT (1<<SENSORS_HANDLE_BITS) + -#define SENSORS_ORIENTATION 0x00000001 -#define SENSORS_ACCELERATION 0x00000002 -#define SENSORS_TEMPERATURE 0x00000004 -#define SENSORS_MAGNETIC_FIELD 0x00000008 -#define SENSORS_LIGHT 0x00000010 -#define SENSORS_PROXIMITY 0x00000020 -#define SENSORS_TRICORDER 0x00000040 -#define SENSORS_ORIENTATION_RAW 0x00000080 -#define SENSORS_MASK 0x000000FF +/** + * Sensor types + */ +#define SENSOR_TYPE_ACCELEROMETER 1 +#define SENSOR_TYPE_MAGNETIC_FIELD 2 +#define SENSOR_TYPE_ORIENTATION 3 +#define SENSOR_TYPE_GYROSCOPE 4 +#define SENSOR_TYPE_LIGHT 5 +#define SENSOR_TYPE_PRESSURE 6 +#define SENSOR_TYPE_TEMPERATURE 7 +#define SENSOR_TYPE_PROXIMITY 8 /** * Values returned by the accelerometer in various locations in the universe. @@ -52,7 +70,7 @@ extern "C" { #define GRAVITY_JUPITER (23.12f) #define GRAVITY_SATURN (8.96f) #define GRAVITY_URANUS (8.69f) -#define GRAVITY_NEPTUN (11.0f) +#define GRAVITY_NEPTUNE (11.0f) #define GRAVITY_PLUTO (0.6f) #define GRAVITY_DEATH_STAR_I (0.000000353036145f) #define GRAVITY_THE_ISLAND (4.815162342f) @@ -63,23 +81,6 @@ extern "C" { /** Minimum magnetic field on Earth's surface */ #define MAGNETIC_FIELD_EARTH_MIN (30.0f) -/** - * Various luminance values during the day (lux) - */ - -#define LIGHT_SUNLIGHT_MAX (120000.0f) -#define LIGHT_SUNLIGHT (110000.0f) -#define LIGHT_SHADE (20000.0f) -#define LIGHT_OVERCAST (10000.0f) -#define LIGHT_SUNRISE (400.0f) -#define LIGHT_CLOUDY (100.0f) - -/* - * Various luminance values during the night (lux) - */ - -#define LIGHT_FULLMOON (0.25f) -#define LIGHT_NO_MOON (0.001f) /** * status of each sensor @@ -92,6 +93,7 @@ extern "C" { /** * Definition of the axis + * ---------------------- * * This API is relative to the screen of the device in its default orientation, * that is, if the device can be used in portrait or landscape, this API @@ -99,23 +101,75 @@ extern "C" { * the axis are not swapped when the device's screen orientation changes. * Higher level services /may/ perform this transformation. * - * -x +x + * x<0 x>0 * ^ * | - * +-----------+--> +y + * +-----------+--> y>0 * | | * | | * | | - * | | / -z + * | | / z<0 * | | / * | | / - * +-----------+/ - * | o O o / - * +----------/+ -y + * O-----------+/ + * |[] [ ] []/ + * +----------/+ y<0 * / * / - * |/ +z + * |/ z>0 (toward the sky) + * + * O: Origin (x=0,y=0,z=0) * + * + * Orientation + * ----------- + * + * All values are angles in degrees. + * + * azimuth: angle between the magnetic north direction and the Y axis, around + * the Z axis (0<=azimuth<360). + * 0=North, 90=East, 180=South, 270=West + * + * pitch: Rotation around X axis (-180<=pitch<=180), with positive values when + * the z-axis moves toward the y-axis. + * + * roll: Rotation around Y axis (-90<=roll<=90), with positive values when + * the z-axis moves AWAY from the x-axis. + * + * Note: This definition is different from yaw, pitch and roll used in aviation + * where the X axis is along the long side of the plane (tail to nose). + * + * + * Acceleration + * ------------ + * + * All values are in SI units (m/s^2) and measure the acceleration of the + * device minus the force of gravity. + * + * x: Acceleration minus Gx on the x-axis + * y: Acceleration minus Gy on the y-axis + * z: Acceleration minus Gz on the z-axis + * + * Examples: + * When the device lies flat on a table and is pushed on its left side + * toward the right, the x acceleration value is positive. + * + * When the device lies flat on a table, the acceleration value is +9.81, + * which correspond to the acceleration of the device (0 m/s^2) minus the + * force of gravity (-9.81 m/s^2). + * + * When the device lies flat on a table and is pushed toward the sky, the + * acceleration value is greater than +9.81, which correspond to the + * acceleration of the device (+A m/s^2) minus the force of + * gravity (-9.81 m/s^2). + * + * + * Magnetic Field + * -------------- + * + * All values are in micro-Tesla (uT) and measure the ambient magnetic + * field in the X, Y and Z axis. + * */ typedef struct { union { @@ -126,7 +180,7 @@ typedef struct { float z; }; struct { - float yaw; + float azimuth; float pitch; float roll; }; @@ -147,7 +201,7 @@ typedef struct { /* x,y,z values of the given sensor */ sensors_vec_t vector; - /* orientation values are in degres */ + /* orientation values are in degrees */ sensors_vec_t orientation; /* acceleration values are in meter per second per second (m/s^2) */ @@ -156,7 +210,7 @@ typedef struct { /* magnetic vector values are in micro-Tesla (uT) */ sensors_vec_t magnetic; - /* temperature is in degres C */ + /* temperature is in degrees centigrade (Celsius) */ float temperature; }; @@ -166,78 +220,138 @@ typedef struct { uint32_t reserved; } sensors_data_t; -/** - * Initialize the module. This is the first entry point - * called and typically initializes the hardware. - * - * @return bit map of available sensors defined by - * the constants SENSORS_XXXX. - */ -uint32_t sensors_control_init(); -/** - * Returns the fd which will be the parameter to - * sensors_data_open. The caller takes ownership - * of this fd. - * - * @return a fd if successful, < 0 on error - */ -int sensors_control_open(); - -/** Activate/deactiveate one or more of the sensors. - * - * @param sensors is a bitmask of the sensors to change. - * @param mask is a bitmask for enabling/disabling sensors. - * - * @return bitmask of SENSORS_XXXX indicating which sensors are enabled - */ -uint32_t sensors_control_activate(uint32_t sensors, uint32_t mask); +struct sensor_t; /** - * Set the delay between sensor events in ms - * - * @return 0 if successful, < 0 on error + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. */ -int sensors_control_delay(int32_t ms); +struct sensors_module_t { + struct hw_module_t common; + + /** + * @return bit map of available sensors defined by + * the constants SENSORS_XXXX. + */ + int (*get_sensors_list)(struct sensors_module_t* module, + struct sensor_t const**); +}; + +struct sensor_t { + const char* name; + const char* vendor; + int version; + int handle; + int type; + float maxRange; + float resolution; + float power; + void* reserved[9]; +}; -/** - * Prepare to read sensor data. - * - * This routiune does NOT take ownership of the fd - * and must not close it. Typcially this routine would - * use a duplicate of the fd parameter. - * - * @param fd from sensors_control_open. - * - * @return 0 if successful, < 0 on error - */ -int sensors_data_open(int fd); /** - * Caller has completed using the sensor data. - * The caller will not be blocked in sensors_data_poll - * when this routine is called. - * - * @return 0 if successful, < 0 on error + * Every device data structure must begin with hw_device_t + * followed by module specific public methods and attributes. */ -int sensors_data_close(); - -/** - * Return sensor data for one of the enabled sensors. - * - * @return SENSOR_XXXX for the returned data, -1 on error - * */ -int sensors_data_poll(sensors_data_t* data, uint32_t sensors_of_interest); - -/** - * @return bit map of available sensors defined by - * the constants SENSORS_XXXX. - */ -uint32_t sensors_data_get_sensors(); - - -#if __cplusplus -} // extern "C" -#endif - -#endif // _HARDWARE_SENSORS_H +struct sensors_control_device_t { + struct hw_device_t common; + + /** + * Returns the fd which will be the parameter to + * sensors_data_device_t::open_data(). + * The caller takes ownership of this fd. This is intended to be + * passed cross processes. + * + * @return a fd if successful, < 0 on error + */ + int (*open_data_source)(struct sensors_control_device_t *dev); + + /** Activate/deactivate one or more of the sensors. + * + * @param sensors is the handle of the sensors to change. + * @param enabled set to 1 to enable, or 0 to disable the sensor. + * + * @return 0 on success, negative errno code otherwise + */ + int (*activate)(struct sensors_control_device_t *dev, + int handle, int enabled); + + /** + * Set the delay between sensor events in ms + * + * @return 0 if successful, < 0 on error + */ + int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms); + + /** + * Causes sensors_data_device_t.poll() to return -EWOULDBLOCK immediately. + */ + int (*wake)(struct sensors_control_device_t *dev); +}; + +struct sensors_data_device_t { + struct hw_device_t common; + + /** + * Prepare to read sensor data. + * + * This routine does NOT take ownership of the fd + * and must not close it. Typically this routine would + * use a duplicate of the fd parameter. + * + * @param fd from sensors_control_open. + * + * @return 0 if successful, < 0 on error + */ + int (*data_open)(struct sensors_data_device_t *dev, int fd); + + /** + * Caller has completed using the sensor data. + * The caller will not be blocked in sensors_data_poll + * when this routine is called. + * + * @return 0 if successful, < 0 on error + */ + int (*data_close)(struct sensors_data_device_t *dev); + + /** + * Return sensor data for one of the enabled sensors. + * + * @return sensor handle for the returned data, 0x7FFFFFFF when + * sensors_control_device_t.wake() is called and -errno on error + * + */ + int (*poll)(struct sensors_data_device_t *dev, + sensors_data_t* data); +}; + + +/** convenience API for opening and closing a device */ + +static inline int sensors_control_open(const struct hw_module_t* module, + struct sensors_control_device_t** device) { + return module->methods->open(module, + SENSORS_HARDWARE_CONTROL, (struct hw_device_t**)device); +} + +static inline int sensors_control_close(struct sensors_control_device_t* device) { + return device->common.close(&device->common); +} + +static inline int sensors_data_open(const struct hw_module_t* module, + struct sensors_data_device_t** device) { + return module->methods->open(module, + SENSORS_HARDWARE_DATA, (struct hw_device_t**)device); +} + +static inline int sensors_data_close(struct sensors_data_device_t* device) { + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_SENSORS_INTERFACE_H diff --git a/include/hardware/wifi.h b/include/hardware/wifi.h index 0b1acdc..23cc92a 100644 --- a/include/hardware/wifi.h +++ b/include/hardware/wifi.h @@ -22,14 +22,14 @@ extern "C" { #endif /** - * Load the wifi driver. + * Load the Wi-Fi driver. * * @return 0 on success, < 0 on failure. */ int wifi_load_driver(); /** - * Unload the wifi driver. + * Unload the Wi-Fi driver. * * @return 0 on success, < 0 on failure. */ @@ -64,59 +64,76 @@ int wifi_connect_to_supplicant(); void wifi_close_supplicant_connection(); /** - * Do a blocking call to get a wifi event and - * return a string representing a wifi event - * when it occurs. + * wifi_wait_for_event() performs a blocking call to + * get a Wi-Fi event and returns a string representing + * a Wi-Fi event when it occurs. * * @param buf is the buffer that receives the event * @param len is the maximum length of the buffer * * @returns number of bytes in buffer, 0 if no - * event, for instance no connection, < 0 if an - * error. + * event (for instance, no connection), and less than 0 + * if there is an error. */ int wifi_wait_for_event(char *buf, size_t len); /** - * Issue a command to the wifi driver. - * - * see \link http://hostap.epitest.fi/wpa_supplicant/devel/ctrl_iface_page.html - * for the list of the standard commands. Android has extended these to include - * support for sending commands to the driver: - * - *------------------------------------------------------------------------------ - * command form of response processing - * Summary of the command - *------------------------------------------------------------------------------ - * "DRIVER START" -> "OK" if successful -> "OK" ? true : false - * Turn on WiFi Hardware - * - * "DRIVER STOP" -> "OK" if successful -> "OK" ? true : false - * Turn off WiFi Hardware - * - * "DRIVER RSSI" -> "<ssid> Rssi xx" -> "%*s %*s %d", &rssi - * Return received signal strength indicator in -db for current AP - * - * "DRIVER LINKSPEED" -> "LinkSpeed xx" -> "%*s %d", &linkspd - * Return link speed in MBPS - * - * "DRIVER MACADDR" -> "Macaddr = xx.xx.xx.xx.xx.xx" -> "%*s = %s", &macadr - * Return mac address of the station - * - * "DRIVER SCAN-ACTIVE" -> "OK" if successful -> "OK" ? true : false - * Set scan type to active - * - * "DRIVER SCAN-PASSIVE" -> "OK" if successful -> "OK" ? true : false - * Set scan type to passive - *------------------------------------------------------------------------------ + * wifi_command() issues a command to the Wi-Fi driver. + * + * Android extends the standard commands listed at + * /link http://hostap.epitest.fi/wpa_supplicant/devel/ctrl_iface_page.html + * to include support for sending commands to the driver: + * + * <table border="2" cellspacing="2" cellpadding="2"> + * <tr> + * <td><strong>Command / Command summary</strong></td> + * <td><strong>Form of Response</strong></td> + * <td><strong>Processing</strong></td> + * </tr> + * <tr> + * <td>DRIVER START<BR> Turn on Wi-Fi Hardware</td> + * <td>OK if successful</td> + * <td>OK ? true : false</td> + * </tr> + * <tr> + * <td>DRIVER STOP<BR> Turn off Wi-Fi hardware</td> + * <td>OK if successful</td> + * <td>OK ? true : false</td> + * </tr> + * <tr> + * <td>DRIVER RSSI<BR> Return received signal strength indicator in -db for current AP</td> + * <td><ssid> Rssi xx</td> + * <td>%*s %*s %d", &rssi</td> + * </tr> + * <tr> + * <td>DRIVER LINKSPEED<BR> Return link speed in MBPS</td> + * <td>LinkSpeed xx</td> + * <td>%*s %d", &linkspd</td> + * </tr> + * <tr> + * <td>DRIVER MACADDR<BR> Return mac address of the station</td> + * <td>Macaddr = xx.xx.xx.xx.xx.xx</td> + * <td>"%*s = %s", &macadr</td> + * </tr> + * <tr> + * <td>DRIVER SCAN-ACTIVE<BR> Set scan type to active</td> + * <td>"OK" if successful</td> + * <td>"OK" ? true : false</td> + * </tr> + * <tr> + * <td>DRIVER SCAN-PASSIVE<BR> Set scan type to passive</td> + * <td>"OK" if successful</td> + * <td>"OK" ? true : false</td> + * </tr> + * </table> * * See libs/android_runtime/android_net_wifi_Wifi.cpp for more information - * on how these and other commands invoked. + * describing how these and other commands are invoked. * * @param command is the string command * @param reply is a buffer to receive a reply string - * @param reply_len on entry is the maximum length of - * reply buffer and on exit the number of + * @param reply_len on entry, this is the maximum length of + * the reply buffer. On exit, the number of * bytes in the reply buffer. * * @return 0 if successful, < 0 if an error. @@ -124,16 +141,17 @@ int wifi_wait_for_event(char *buf, size_t len); int wifi_command(const char *command, char *reply, size_t *reply_len); /** - * Issues a dhcp request returning the acquired - * information. All IPV4 addresses/mask are in - * network byte order. + * do_dhcp_request() issues a dhcp request and returns the acquired + * information. + * + * All IPV4 addresses/mask are in network byte order. * * @param ipaddr return the assigned IPV4 address * @param gateway return the gateway being used * @param mask return the IPV4 mask - * @param dns1 return the IPV4 address of a dns server - * @param dns2 return the IPV4 address of a dns server - * @param serverAddress return the IPV4 address of dhcp server + * @param dns1 return the IPV4 address of a DNS server + * @param dns2 return the IPV4 address of a DNS server + * @param server return the IPV4 address of DHCP server * @param lease return the length of lease in seconds. * * @return 0 if successful, < 0 if error. @@ -142,7 +160,7 @@ int do_dhcp_request(int *ipaddr, int *gateway, int *mask, int *dns1, int *dns2, int *server, int *lease); /** - * Return the error string of the last do_dhcp_request. + * Return the error string of the last do_dhcp_request(). */ const char *get_dhcp_error_string(); diff --git a/led/Android.mk b/led/Android.mk index 3ecaff8..2b6ac0b 100644 --- a/led/Android.mk +++ b/led/Android.mk @@ -1,12 +1,15 @@ # Copyright 2006 The Android Open Source Project -ifeq ($(TARGET_PRODUCT),sooner) +ifeq ($(TARGET_DEVICE),sooner) LOCAL_SRC_FILES += led/led_sardine.c -else -ifeq ($(TARGET_PRODUCT),dream) +LOCAL_CFLAGS += -DCONFIG_LED_SARDINE +endif +ifeq ($(TARGET_DEVICE),dream) LOCAL_SRC_FILES += led/led_trout.c -else -LOCAL_SRC_FILES += led/led_stub.c +LOCAL_CFLAGS += -DCONFIG_LED_TROUT endif +ifeq ($(QEMU_HARDWARE),true) +LOCAL_CFLAGS += -DCONFIG_LED_QEMU endif +LOCAL_SRC_FILES += led/led_stub.c diff --git a/led/led_qemu.c b/led/led_qemu.c new file mode 100644 index 0000000..c98402b --- /dev/null +++ b/led/led_qemu.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "qemu.h" + +int +qemu_set_led_state(unsigned color, int on, int off) +{ + qemu_control_command( "set_led_state:%08x:%d:%d", color, on, off ); + return 0; +} diff --git a/led/led_sardine.c b/led/led_sardine.c index a53729f..a5e6fad 100644 --- a/led/led_sardine.c +++ b/led/led_sardine.c @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <hardware/led.h> #include <sys/types.h> #include <sys/stat.h> @@ -27,7 +42,7 @@ write_string(const char* file, const char* string, int len) return amt >= 0 ? 0 : errno; } -int set_led_state(unsigned colorARGB, int onMS, int offMS) +int sardine_set_led_state(unsigned colorARGB, int onMS, int offMS) { int len; char buf[30]; diff --git a/led/led_stub.c b/led/led_stub.c index 644efe3..1deac2f 100644 --- a/led/led_stub.c +++ b/led/led_stub.c @@ -1,7 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <hardware/led.h> +typedef int (*LedFunc)(unsigned, int, int); + +#ifdef CONFIG_LED_SARDINE +extern int sardine_set_led_state(unsigned, int, int); +# define HW_LED_FUNC sardine_set_led_state +#endif + +#ifdef CONFIG_LED_TROUT +extern int trout_set_led_state(unsigned, int, int); +# define HW_LED_FUNC trout_set_led_state +#endif + +#ifdef CONFIG_LED_QEMU +#include "qemu.h" +static int +qemu_set_led_state(unsigned color, int on, int off) +{ + qemu_control_command( "set_led_state:%08x:%d:%d", color, on, off ); + return 0; +} +#endif + int set_led_state(unsigned color, int on, int off) { +#ifdef CONFIG_LED_QEMU + QEMU_FALLBACK(set_led_state(color,on,off)); +#endif +#ifdef HW_LED_FUNC + return HW_LED_FUNC(color, on, off); +#else return 0; +#endif } diff --git a/led/led_trout.c b/led/led_trout.c index 847b6bc..99d6bb0 100644 --- a/led/led_trout.c +++ b/led/led_trout.c @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <hardware/led.h> #include <sys/types.h> #include <sys/stat.h> @@ -38,7 +53,7 @@ write_string(const char* file, const char* string, int len) return amt >= 0 ? 0 : errno; } -int set_led_state(unsigned colorARGB, int onMS, int offMS) +int trout_set_led_state(unsigned colorARGB, int onMS, int offMS) { int len; char buf[30]; diff --git a/modules/README.android b/modules/README.android new file mode 100644 index 0000000..a79a1d5 --- /dev/null +++ b/modules/README.android @@ -0,0 +1,21 @@ +Default (and possibly architecture dependents) HAL modules go here. + + +libhardware.so eventually should contain *just* the HAL hub +(hardware.c), everything in it should be rewritten as modules. + +Modules are .so in /system/libs/hw/ and have a well defined naming +convention: + + /system/libs/hw/<*_HARDWARE_MODULE_ID>.<ro.arch>.so + /system/libs/hw/<*_HARDWARE_MODULE_ID>.default.so + +They also have a well defined interface which lives in include/hardware/. + +A module can have several variants: "default", "arch" and "board", and they're +loaded in the "board", "arch" and "default" order. +The source code for the "board" variant, usually lives under partners/... + +The source code for "default" and "arch" would usually +live under hardware/modules/. + diff --git a/modules/overlay/Android.mk b/modules/overlay/Android.mk new file mode 100644 index 0000000..44b55af --- /dev/null +++ b/modules/overlay/Android.mk @@ -0,0 +1,26 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +LOCAL_PATH := $(call my-dir) + +# HAL module implemenation, not prelinked and stored in +# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SRC_FILES := overlay.cpp +LOCAL_MODULE := overlay.trout +include $(BUILD_SHARED_LIBRARY) diff --git a/modules/overlay/README.android b/modules/overlay/README.android new file mode 100644 index 0000000..971d619 --- /dev/null +++ b/modules/overlay/README.android @@ -0,0 +1,3 @@ + +Skeleton for the "overlay" HAL module. + diff --git a/modules/overlay/overlay.cpp b/modules/overlay/overlay.cpp new file mode 100644 index 0000000..3e4c02b --- /dev/null +++ b/modules/overlay/overlay.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "Overlay" + +#include <hardware/hardware.h> +#include <hardware/overlay.h> + +#include <fcntl.h> +#include <errno.h> + +#include <cutils/log.h> +#include <cutils/atomic.h> + +/*****************************************************************************/ + +struct overlay_context_t { + struct overlay_device_t device; + /* our private state goes below here */ +}; + + +static int overlay_device_open(const struct hw_module_t* module, const char* name, + struct hw_device_t** device); + +static struct hw_module_methods_t overlay_module_methods = { + open: overlay_device_open +}; + +const struct overlay_module_t HAL_MODULE_INFO_SYM = { + common: { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: OVERLAY_HARDWARE_MODULE_ID, + name: "Sample Overlay module", + author: "The Android Open Source Project", + methods: &overlay_module_methods, + } +}; + +/*****************************************************************************/ + +/* + * This is the overlay_t object, it is returned to the user and represents + * an overlay. here we use a subclass, where we can store our own state. + * Notice the use of "overlay_handle_t", which is an "opaque" marshallable + * handle, it can contains any number of ints and up to 4 filedescriptors. + * In this example we store no fd and 2 ints. + * This handles will be passed across processes and possibly given to other + * HAL modules (for instance video decode modules). + */ + +class overlay_object : public overlay_t { + + struct handle_t : public overlay_handle_t { + /* add the data fields we need here, for instance: */ + int width; + int height; + }; + + handle_t mHandle; + + static overlay_handle_t const* getHandleRef(struct overlay_t* overlay) { + /* returns a reference to the handle, caller doesn't take ownership */ + return &(static_cast<overlay_object *>(overlay)->mHandle); + } + +public: + overlay_object() { + this->overlay_t::getHandleRef = getHandleRef; + mHandle.numFds = 0; + mHandle.numInts = 2; // extra ints we have in our handle + } +}; + +/*****************************************************************************/ + +static int overlay_get(struct overlay_device_t *dev, int name) { + int result = -1; + switch (name) { + case OVERLAY_MINIFICATION_LIMIT: + result = 0; // 0 = no limit + break; + case OVERLAY_MAGNIFICATION_LIMIT: + result = 0; // 0 = no limit + break; + case OVERLAY_SCALING_FRAC_BITS: + result = 0; // 0 = infinite + break; + case OVERLAY_ROTATION_STEP_DEG: + result = 90; // 90 rotation steps (for instance) + break; + case OVERLAY_HORIZONTAL_ALIGNMENT: + result = 1; // 1-pixel alignment + break; + case OVERLAY_VERTICAL_ALIGNMENT: + result = 1; // 1-pixel alignment + break; + case OVERLAY_WIDTH_ALIGNMENT: + result = 1; // 1-pixel alignment + break; + case OVERLAY_HEIGHT_ALIGNMENT: + result = 1; // 1-pixel alignment + break; + } + return result; +} + +static overlay_t* overlay_createOverlay(struct overlay_device_t *dev, + uint32_t w, uint32_t h, int32_t format) +{ + /* check the input params, reject if not supported or invalid */ + switch (format) { + case OVERLAY_FORMAT_RGBA_8888: + case OVERLAY_FORMAT_RGB_565: + case OVERLAY_FORMAT_BGRA_8888: + case OVERLAY_FORMAT_YCbCr_422_SP: + case OVERLAY_FORMAT_YCbCr_420_SP: + case OVERLAY_FORMAT_YCbCr_422_P: + case OVERLAY_FORMAT_YCbCr_420_P: + break; + default: + return NULL; + } + + /* Create overlay object. Talk to the h/w here and adjust to what it can + * do. the overlay_t returned can be a C++ object, subclassing overlay_t + * if needed. + * + * we probably want to keep a list of the overlay_t created so they can + * all be cleaned up in overlay_close(). + */ + return new overlay_object( /* pass needed params here*/ ); +} + +static void overlay_destroyOverlay(struct overlay_device_t *dev, + overlay_t* overlay) +{ + /* free resources associated with this overlay_t */ + delete overlay; +} + +static int overlay_setPosition(struct overlay_device_t *dev, + overlay_t* overlay, + int x, int y, uint32_t w, uint32_t h) { + /* set this overlay's position (talk to the h/w) */ + return -EINVAL; +} + +static int overlay_getPosition(struct overlay_device_t *dev, + overlay_t* overlay, + int* x, int* y, uint32_t* w, uint32_t* h) { + /* get this overlay's position */ + return -EINVAL; +} + +static int overlay_setParameter(struct overlay_device_t *dev, + overlay_t* overlay, int param, int value) { + + int result = 0; + /* set this overlay's parameter (talk to the h/w) */ + switch (param) { + case OVERLAY_ROTATION_DEG: + break; + case OVERLAY_DITHER: + break; + default: + result = -EINVAL; + break; + } + return result; +} + +static int overlay_swapBuffers(struct overlay_device_t *dev, + overlay_t* overlay) { + /* swap this overlay's buffers (talk to the h/w), this call probably + * wants to block until a new buffer is available */ + return -EINVAL; +} + +static int overlay_getOffset(struct overlay_device_t *dev, + overlay_t* overlay) { + /* return the current's buffer offset */ + return 0; +} + +static int overlay_getMemory(struct overlay_device_t *dev) { + /* maps this overlay if possible. don't forget to unmap in destroyOverlay */ + return -EINVAL; +} + +/*****************************************************************************/ + + +static int overlay_device_close(struct hw_device_t *dev) +{ + struct overlay_context_t* ctx = (struct overlay_context_t*)dev; + if (ctx) { + /* free all resources associated with this device here */ + free(ctx); + } + return 0; +} + + +static int overlay_device_open(const struct hw_module_t* module, const char* name, + struct hw_device_t** device) +{ + int status = -EINVAL; + if (!strcmp(name, OVERLAY_HARDWARE_OVERLAY0)) { + struct overlay_context_t *dev; + dev = (overlay_context_t*)malloc(sizeof(*dev)); + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast<hw_module_t*>(module); + dev->device.common.close = overlay_device_close; + + dev->device.get = overlay_get; + dev->device.createOverlay = overlay_createOverlay; + dev->device.destroyOverlay = overlay_destroyOverlay; + dev->device.setPosition = overlay_setPosition; + dev->device.getPosition = overlay_getPosition; + dev->device.setParameter = overlay_setParameter; + dev->device.swapBuffers = overlay_swapBuffers; + dev->device.getOffset = overlay_getOffset; + dev->device.getMemory = overlay_getMemory; + + *device = &dev->device.common; + status = 0; + } + return status; +} diff --git a/power/Android.mk b/power/Android.mk index fe671a5..a524d0e 100644 --- a/power/Android.mk +++ b/power/Android.mk @@ -2,3 +2,7 @@ LOCAL_SRC_FILES += power/power.c +ifeq ($(QEMU_HARDWARE),true) + LOCAL_SRC_FILES += power/power_qemu.c + LOCAL_CFLAGS += -DQEMU_POWER=1 +endif diff --git a/power/power.c b/power/power.c index 907726a..4c5ebd3 100644 --- a/power/power.c +++ b/power/power.c @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <hardware/power.h> #include <fcntl.h> #include <errno.h> @@ -15,21 +30,30 @@ #define LOG_TAG "power" #include <utils/Log.h> +#include "qemu.h" +#ifdef QEMU_POWER +#include "power_qemu.h" +#endif + enum { ACQUIRE_PARTIAL_WAKE_LOCK = 0, - ACQUIRE_FULL_WAKE_LOCK, RELEASE_WAKE_LOCK, REQUEST_STATE, OUR_FD_COUNT }; -const char * const PATHS[] = { +const char * const OLD_PATHS[] = { "/sys/android_power/acquire_partial_wake_lock", - "/sys/android_power/acquire_full_wake_lock", "/sys/android_power/release_wake_lock", "/sys/android_power/request_state" }; +const char * const NEW_PATHS[] = { + "/sys/power/wake_lock", + "/sys/power/wake_unlock", + "/sys/power/state" +}; + const char * const AUTO_OFF_TIMEOUT_DEV = "/sys/android_power/auto_off_timeout"; const char * const LCD_BACKLIGHT = "/sys/class/leds/lcd-backlight/brightness"; @@ -41,6 +65,8 @@ static int g_initialized = 0; static int g_fds[OUR_FD_COUNT]; static int g_error = 1; +static const char *off_state = "mem"; +static const char *on_state = "on"; static int64_t systemTime() { @@ -50,21 +76,22 @@ static int64_t systemTime() return t.tv_sec*1000000000LL + t.tv_nsec; } -static void -open_file_descriptors(void) +static int +open_file_descriptors(const char * const paths[]) { int i; for (i=0; i<OUR_FD_COUNT; i++) { - int fd = open(PATHS[i], O_RDWR); + int fd = open(paths[i], O_RDWR); if (fd < 0) { - fprintf(stderr, "fatal error opening \"%s\"\n", PATHS[i]); + fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]); g_error = errno; - return; + return -1; } g_fds[i] = fd; } g_error = 0; + return 0; } static inline void @@ -74,7 +101,11 @@ initialize_fds(void) //pthread_once(&g_initialized, open_file_descriptors); // XXX: not this: if (g_initialized == 0) { - open_file_descriptors(); + if(open_file_descriptors(NEW_PATHS) < 0) { + open_file_descriptors(OLD_PATHS); + on_state = "wake"; + off_state = "standby"; + } g_initialized = 1; } } @@ -93,9 +124,6 @@ acquire_wake_lock(int lock, const char* id) if (lock == PARTIAL_WAKE_LOCK) { fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK]; } - else if (lock == FULL_WAKE_LOCK) { - fd = g_fds[ACQUIRE_FULL_WAKE_LOCK]; - } else { return EINVAL; } @@ -138,23 +166,29 @@ static void set_a_light(const char* path, int value) { int fd; + static int already_warned = 0; // LOGI("set_a_light(%s, %d)\n", path, value); fd = open(path, O_RDWR); - if (fd) { + if (fd >= 0) { char buffer[20]; int bytes = sprintf(buffer, "%d\n", value); write(fd, buffer, bytes); close(fd); } else { - LOGE("set_a_light failed to open %s\n", path); + if (already_warned == 0) { + LOGE("set_a_light failed to open %s\n", path); + already_warned = 1; + } } } int set_light_brightness(unsigned int mask, unsigned int brightness) { + QEMU_FALLBACK(set_light_brightness(mask,brightness)); + initialize_fds(); // LOGI("set_light_brightness mask=0x%08x brightness=%d now=%lld g_error=%s\n", @@ -179,6 +213,8 @@ set_light_brightness(unsigned int mask, unsigned int brightness) int set_screen_state(int on) { + QEMU_FALLBACK(set_screen_state(on)); + //LOGI("*** set_screen_state %d", on); initialize_fds(); @@ -191,14 +227,12 @@ set_screen_state(int on) char buf[32]; int len; if(on) - len = sprintf(buf, "wake"); + len = sprintf(buf, on_state); else - len = sprintf(buf, "standby"); + len = sprintf(buf, off_state); len = write(g_fds[REQUEST_STATE], buf, len); if(len < 0) { LOGE("Failed setting last user activity: g_error=%d\n", g_error); } return 0; } - - diff --git a/power/power_qemu.c b/power/power_qemu.c new file mode 100644 index 0000000..75f52b2 --- /dev/null +++ b/power/power_qemu.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "qemu.h" +#include "power_qemu.h" +#include <fcntl.h> +#include <errno.h> +#include <hardware/power.h> + +static void +set_a_light(const char* name, unsigned brightness) +{ + qemu_control_command( "power:light:brightness:%s:%d", + name, brightness ); +} + +int +qemu_set_light_brightness(unsigned int mask, unsigned int brightness) +{ + if (mask & KEYBOARD_LIGHT) { + set_a_light("keyboard_backlight", brightness); + } + if (mask & SCREEN_LIGHT) { + set_a_light("lcd_backlight", brightness); + } + if (mask & BUTTON_LIGHT) { + set_a_light("button_backlight", brightness); + } + return 0; +} + + +int +qemu_set_screen_state(int on) +{ + qemu_control_command( "power:screen_state:%s", on ? "wake" : "standby" ); + return 0; +} + diff --git a/power/power_qemu.h b/power/power_qemu.h new file mode 100644 index 0000000..3004950 --- /dev/null +++ b/power/power_qemu.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _power_qemu_h +#define _power_qemu_h + +#include <stdint.h> + +extern int +qemu_set_light_brightness(unsigned int mask, unsigned int brightness); + +extern int +qemu_set_screen_state(int on); + +#endif /* _power_qemu_h */ @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _libs_hardware_qemu_h +#define _libs_hardware_qemu_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef QEMU_HARDWARE + +/* returns 1 iff we're running in the emulator */ +extern int qemu_check(void); + +/* a structure used to hold enough state to connect to a given + * QEMU communication channel, either through a qemud socket or + * a serial port. + * + * initialize the structure by zero-ing it out + */ +typedef struct { + char is_inited; + char is_available; + char is_qemud; + char is_tty; + char device[32]; +} QemuChannel; + +/* try to open a qemu communication channel. + * returns a file descriptor on success, or -1 in case of + * error. + * + * 'channel' must be a QemuChannel structure that is empty + * on the first call. You can call this function several + * time to re-open the channel using the same 'channel' + * object to speed things a bit. + */ +extern int qemu_channel_open( QemuChannel* channel, + const char* name, + int mode ); + +/* create a command made of a 4-hexchar prefix followed + * by the content. the prefix contains the content's length + * in hexadecimal coding. + * + * 'buffer' must be at last 6 bytes + * returns -1 in case of overflow, or the command's total length + * otherwise (i.e. content length + 4) + */ +extern int qemu_command_format( char* buffer, + int buffer_size, + const char* format, + ... ); + +/* directly sends a command through the 'control' channel. + * this will open the channel, send the formatted command, then + * close the channel automatically. + * returns 0 on success, or -1 on error. + */ +extern int qemu_control_command( const char* fmt, ... ); + +/* sends a question to the control channel, then receive an answer in + * a user-allocated buffer. returns the lenght of the answer, or -1 + * in case of error. + * + * 'question' *must* have been formatted through qemu_command_format + */ +extern int qemu_control_query( const char* question, int questionlen, + char* answer, int answersize ); + +#endif /* QEMU_HARDWARE */ + +/* use QEMU_FALLBACK(call) to call a QEMU-specific callback */ +/* use QEMU_FALLBACK_VOID(call) if the function returns void */ +#ifdef QEMU_HARDWARE +# define QEMU_FALLBACK(x) \ + do { \ + if (qemu_check()) \ + return qemu_ ## x ; \ + } while (0) +# define QEMU_FALLBACK_VOID(x) \ + do { \ + if (qemu_check()) { \ + qemu_ ## x ; \ + return; \ + } \ + } while (0) +#else +# define QEMU_FALLBACK(x) ((void)0) +# define QEMU_FALLBACK_VOID(x) ((void)0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _libs_hardware_qemu_h */ diff --git a/qemu/Android.mk b/qemu/Android.mk new file mode 100644 index 0000000..5171754 --- /dev/null +++ b/qemu/Android.mk @@ -0,0 +1,3 @@ +ifeq ($(QEMU_HARDWARE),true) +LOCAL_SRC_FILES += qemu/qemu.c +endif diff --git a/qemu/qemu.c b/qemu/qemu.c new file mode 100644 index 0000000..2631c58 --- /dev/null +++ b/qemu/qemu.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* this file contains various functions used by all libhardware modules + * that support QEMU emulation + */ +#include "qemu.h" +#define LOG_TAG "hardware-qemu" +#include <cutils/log.h> +#include <cutils/properties.h> +#include <cutils/sockets.h> +#include <errno.h> +#include <fcntl.h> +#include <termios.h> +#include <stdio.h> +#include <stdarg.h> + +#define QEMU_DEBUG 0 + +#if QEMU_DEBUG +# define D(...) LOGD(__VA_ARGS__) +#else +# define D(...) ((void)0) +#endif + + +int +qemu_check(void) +{ + static int in_qemu = -1; + + if (__builtin_expect(in_qemu < 0,0)) { + char propBuf[PROPERTY_VALUE_MAX]; + property_get("ro.kernel.qemu", propBuf, ""); + in_qemu = (propBuf[0] == '1'); + } + return in_qemu; +} + + +int +qemu_channel_open( QemuChannel* channel, + const char* name, + int mode ) +{ + int fd = -1; + + /* initialize the channel is needed */ + if (!channel->is_inited) + { + int done = 0; + + // try to connect to qemud socket first + do { + snprintf(channel->device, sizeof channel->device, + "qemud_%s", name); + + fd = socket_local_client( channel->device, + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_STREAM ); + if (fd < 0) { + D("no '%s' control socket available: %s", + channel->device, strerror(errno)); + break; + } + close(fd); + channel->is_qemud = 1; + done = 1; + } while (0); + + // otherwise, look for a kernel-provided device name + if (!done) do { + char key[PROPERTY_KEY_MAX]; + char prop[PROPERTY_VALUE_MAX]; + int ret; + + ret = snprintf(key, sizeof key, "ro.kernel.android.%s", name); + if (ret >= (int)sizeof key) + break; + + if (property_get(key, prop, "") == 0) { + D("no kernel-provided %s device name", name); + break; + } + + ret = snprintf(channel->device, sizeof channel->device, + "/dev/%s", prop); + if (ret >= (int)sizeof channel->device) { + D("%s device name too long: '%s'", name, prop); + break; + } + channel->is_tty = !memcmp("/dev/tty", channel->device, 8); + done = 1; + + } while (0); + + channel->is_available = done; + channel->is_inited = 1; + } + + /* try to open the file */ + if (!channel->is_available) { + fd = -1; + errno = ENOENT; + } else if (channel->is_qemud) { + do { + fd = socket_local_client( channel->device, + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_STREAM ); + } while (fd < 0 && errno == EINTR); + } else { + do { + fd = open(channel->device, mode); + } while (fd < 0 && errno == EINTR); + + /* disable ECHO on serial lines */ + if (fd >= 0 && channel->is_tty) { + struct termios ios; + tcgetattr( fd, &ios ); + ios.c_lflag = 0; /* disable ECHO, ICANON, etc... */ + tcsetattr( fd, TCSANOW, &ios ); + } + } + return fd; +} + + +static int +qemu_command_vformat( char* buffer, + int buffer_size, + const char* format, + va_list args ) +{ + char header[5]; + int len; + + if (buffer_size < 6) + return -1; + + len = vsnprintf(buffer+4, buffer_size-4, format, args); + if (len >= buffer_size-4) + return -1; + + snprintf(header, sizeof header, "%04x", len); + memcpy(buffer, header, 4); + return len + 4; +} + +extern int +qemu_command_format( char* buffer, + int buffer_size, + const char* format, + ... ) +{ + va_list args; + int ret; + + va_start(args, format); + ret = qemu_command_format(buffer, buffer_size, format, args); + va_end(args); + return ret; +} + + +static int +qemu_control_fd(void) +{ + static QemuChannel channel[1]; + int fd; + + fd = qemu_channel_open( channel, "control", O_RDWR ); + if (fd < 0) { + D("%s: could not open control channel: %s", __FUNCTION__, + strerror(errno)); + } + return fd; +} + +static int +qemu_control_write( int fd, const char* cmd, int len ) +{ + int len2; + do { + len2 = write(fd, cmd, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} + +static int +qemu_control_read( int fd, char* buff, int len ) +{ + int len2; + do { + len2 = read(fd, buff, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} + +static int +qemu_control_send(const char* cmd, int len) +{ + int fd, len2; + + if (len < 0) { + errno = EINVAL; + return -1; + } + + fd = qemu_control_fd(); + if (fd < 0) + return -1; + + len2 = qemu_control_write(fd, cmd, len); + close(fd); + if (len2 != len) { + D("%s: could not send everything %d < %d", + __FUNCTION__, len2, len); + return -1; + } + return 0; +} + + +int +qemu_control_command( const char* fmt, ... ) +{ + va_list args; + char command[256]; + int len, fd; + + va_start(args, fmt); + len = qemu_command_vformat( command, sizeof command, fmt, args ); + va_end(args); + + if (len < 0 || len >= (int)sizeof command) { + if (len < 0) { + D("%s: could not send: %s", __FUNCTION__, strerror(errno)); + } else { + D("%s: too large %d > %d", __FUNCTION__, len, (int)(sizeof command)); + } + errno = EINVAL; + return -1; + } + + return qemu_control_send( command, len ); +} + +extern int qemu_control_query( const char* question, int questionlen, + char* answer, int answersize ) +{ + int ret, fd, len, result = -1; + char header[5], *end; + + if (questionlen <= 0) { + errno = EINVAL; + return -1; + } + + fd = qemu_control_fd(); + if (fd < 0) + return -1; + + ret = qemu_control_write( fd, question, questionlen ); + if (ret != questionlen) { + D("%s: could not write all: %d < %d", __FUNCTION__, + ret, questionlen); + goto Exit; + } + + /* read a 4-byte header giving the length of the following content */ + ret = qemu_control_read( fd, header, 4 ); + if (ret != 4) { + D("%s: could not read header (%d != 4)", + __FUNCTION__, ret); + goto Exit; + } + + header[5] = 0; + len = strtol( header, &end, 16 ); + if ( len < 0 || end == NULL || end != header+4 || len > answersize ) { + D("%s: could not parse header: '%s'", + __FUNCTION__, header); + goto Exit; + } + + /* read the answer */ + ret = qemu_control_read( fd, answer, len ); + if (ret != len) { + D("%s: could not read all of answer %d < %d", + __FUNCTION__, ret, len); + goto Exit; + } + + result = len; + +Exit: + close(fd); + return result; +} diff --git a/qemu_tracing/qemu_tracing.c b/qemu_tracing/qemu_tracing.c index aacd1aa..847102c 100644 --- a/qemu_tracing/qemu_tracing.c +++ b/qemu_tracing/qemu_tracing.c @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <stdio.h> #include <string.h> #include <errno.h> diff --git a/sensors/Android.mk b/sensors/Android.mk deleted file mode 100644 index 00fdbad..0000000 --- a/sensors/Android.mk +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2008 The Android Open Source Project - -ifeq ($(TARGET_PRODUCT),dream) -LOCAL_SRC_FILES += sensors/sensors_trout.c -else -LOCAL_SRC_FILES += sensors/sensors_stub.c -endif - diff --git a/sensors/sensors_stub.c b/sensors/sensors_stub.c deleted file mode 100644 index c096cf2..0000000 --- a/sensors/sensors_stub.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <hardware/sensors.h> -#include <unistd.h> - - -uint32_t sensors_control_init() { - return 0; -} - -/* returns a fd where to read the events from. the caller takes - * ownership of this fd */ -int sensors_control_open() { - return -1; -} - -/* returns a bitmask indicating which sensors are enabled */ -uint32_t sensors_control_activate(uint32_t sensors, uint32_t mask) { - return 0; -} - -/* set the delay between sensor events in ms */ -int sensors_control_delay(int32_t ms) { - return -1; -} - -/* initialize the sensor data read. doesn't take ownership of the fd */ -int sensors_data_open(int fd) { - return 0; -} - -/* done with sensor data */ -int sensors_data_close() { - return -1; -} - -/* returns a bitmask indicating which sensors have changed */ -int sensors_data_poll(sensors_data_t* data, uint32_t sensors_of_interest) { - usleep(60000000); - return 0; -} - -/* returns available sensors */ -uint32_t sensors_data_get_sensors() { - return 0; -} diff --git a/sensors/sensors_trout.c b/sensors/sensors_trout.c deleted file mode 100644 index f3c0b3a..0000000 --- a/sensors/sensors_trout.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "Sensors" - -#include <hardware/sensors.h> -#include <fcntl.h> -#include <errno.h> -#include <dirent.h> -#include <math.h> -#include <poll.h> - -#include <linux/input.h> -#include <linux/akm8976.h> - -#include <cutils/log.h> -#include <cutils/atomic.h> - -/*****************************************************************************/ - -#define AKM_DEVICE_NAME "/dev/akm8976_aot" - -#define SUPPORTED_SENSORS (SENSORS_ORIENTATION | \ - SENSORS_ACCELERATION | \ - SENSORS_MAGNETIC_FIELD | \ - SENSORS_ORIENTATION_RAW) - - -// sensor IDs must be a power of two and -// must match values in SensorManager.java -#define EVENT_TYPE_ACCEL_X ABS_X -#define EVENT_TYPE_ACCEL_Y ABS_Z -#define EVENT_TYPE_ACCEL_Z ABS_Y -#define EVENT_TYPE_ACCEL_STATUS ABS_WHEEL - -#define EVENT_TYPE_YAW ABS_RX -#define EVENT_TYPE_PITCH ABS_RY -#define EVENT_TYPE_ROLL ABS_RZ -#define EVENT_TYPE_ORIENT_STATUS ABS_RUDDER - -#define EVENT_TYPE_MAGV_X ABS_HAT0X -#define EVENT_TYPE_MAGV_Y ABS_HAT0Y -#define EVENT_TYPE_MAGV_Z ABS_BRAKE - -#define EVENT_TYPE_TEMPERATURE ABS_THROTTLE -#define EVENT_TYPE_STEP_COUNT ABS_GAS - -// 720 LSG = 1G -#define LSG (720.0f) - -// conversion of acceleration data to SI units (m/s^2) -#define CONVERT_A (GRAVITY_EARTH / LSG) -#define CONVERT_A_X (CONVERT_A) -#define CONVERT_A_Y (-CONVERT_A) -#define CONVERT_A_Z (CONVERT_A) - -// conversion of magnetic data to uT units -#define CONVERT_M (1.0f/16.0f) -#define CONVERT_M_X (CONVERT_M) -#define CONVERT_M_Y (CONVERT_M) -#define CONVERT_M_Z (CONVERT_M) - -#define SENSOR_STATE_MASK (0x7FFF) - -/*****************************************************************************/ - -static int sAkmFD = -1; -static uint32_t sActiveSensors = 0; - -/*****************************************************************************/ - -/* - * We use a Least Mean Squares filter to smooth out the output of the yaw - * sensor. - * - * The goal is to estimate the output of the sensor based on previous acquired - * samples. - * - * We approximate the input by a line with the equation: - * Z(t) = a * t + b - * - * We use the Least Mean Squares method to calculate a and b so that the - * distance between the line and the measured COUNT inputs Z(t) is minimal. - * - * In practice we only need to compute b, which is the value we're looking for - * (it's the estimated Z at t=0). However, to improve the latency a little bit, - * we're going to discard a certain number of samples that are too far from - * the estimated line and compute b again with the new (trimmed down) samples. - * - * notes: - * 'a' is the slope of the line, and physicaly represent how fast the input - * is changing. In our case, how fast the yaw is changing, that is, how fast the - * user is spinning the device (in degre / nanosecond). This value should be - * zero when the device is not moving. - * - * The minimum distance between the line and the samples (which we are not - * explicitely computing here), is an indication of how bad the samples are - * and gives an idea of the "quality" of the estimation (well, really of the - * sensor values). - * - */ - -/* sensor rate in me */ -#define SENSORS_RATE_MS 20 -/* timeout (constant value) in ms */ -#define SENSORS_TIMEOUT_MS 100 -/* # of samples to look at in the past for filtering */ -#define COUNT 24 -/* prediction ratio */ -#define PREDICTION_RATIO (1.0f/3.0f) -/* prediction time in seconds (>=0) */ -#define PREDICTION_TIME ((SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO) - -static float mV[COUNT*2]; -static float mT[COUNT*2]; -static int mIndex; - -static inline -float normalize(float x) -{ - x *= (1.0f / 360.0f); - if (fabsf(x) >= 0.5f) - x = x - ceilf(x + 0.5f) + 1.0f; - if (x < 0) - x += 1.0f; - x *= 360.0f; - return x; -} - -static void LMSInit(void) -{ - memset(mV, 0, sizeof(mV)); - memset(mT, 0, sizeof(mT)); - mIndex = COUNT; -} - -static float LMSFilter(int64_t time, int v) -{ - const float ns = 1.0f / 1000000000.0f; - const float t = time*ns; - float v1 = mV[mIndex]; - if ((v-v1) > 180) { - v -= 360; - } else if ((v1-v) > 180) { - v += 360; - } - /* Manage the circular buffer, we write the data twice spaced by COUNT - * values, so that we don't have to memcpy() the array when it's full */ - mIndex++; - if (mIndex >= COUNT*2) - mIndex = COUNT; - mV[mIndex] = v; - mT[mIndex] = t; - mV[mIndex-COUNT] = v; - mT[mIndex-COUNT] = t; - - float A, B, C, D, E; - float a, b; - int i; - - A = B = C = D = E = 0; - for (i=0 ; i<COUNT-1 ; i++) { - const int j = mIndex - 1 - i; - const float Z = mV[j]; - const float T = 0.5f*(mT[j] + mT[j+1]) - t; - float dT = mT[j] - mT[j+1]; - dT *= dT; - A += Z*dT; - B += T*(T*dT); - C += (T*dT); - D += Z*(T*dT); - E += dT; - } - b = (A*B + C*D) / (E*B + C*C); - a = (E*b - A) / C; - float f = b + PREDICTION_TIME*a; - - //LOGD("A=%f, B=%f, C=%f, D=%f, E=%f", A,B,C,D,E); - //LOGD("%lld %d %f %f", time, v, f, a); - - f = normalize(f); - return f; -} - -/*****************************************************************************/ - -static int open_input() -{ - /* scan all input drivers and look for "compass" */ - int fd = -1; - const char *dirname = "/dev/input"; - char devname[PATH_MAX]; - char *filename; - DIR *dir; - struct dirent *de; - dir = opendir(dirname); - if(dir == NULL) - return -1; - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - while((de = readdir(dir))) { - if(de->d_name[0] == '.' && - (de->d_name[1] == '\0' || - (de->d_name[1] == '.' && de->d_name[2] == '\0'))) - continue; - strcpy(filename, de->d_name); - fd = open(devname, O_RDONLY); - if (fd>=0) { - char name[80]; - if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { - name[0] = '\0'; - } - if (!strcmp(name, "compass")) { - LOGD("using %s (name=%s)", devname, name); - break; - } - close(fd); - fd = -1; - } - } - closedir(dir); - - if (fd < 0) { - LOGE("Couldn't find or open 'compass' driver (%s)", strerror(errno)); - } - return fd; -} - -static int open_akm() -{ - if (sAkmFD <= 0) { - sAkmFD = open(AKM_DEVICE_NAME, O_RDONLY); - LOGD("%s, fd=%d", __PRETTY_FUNCTION__, sAkmFD); - LOGE_IF(sAkmFD<0, "Couldn't open %s (%s)", - AKM_DEVICE_NAME, strerror(errno)); - if (sAkmFD >= 0) { - sActiveSensors = 0; - } - } - return sAkmFD; -} - -static void close_akm() -{ - if (sAkmFD > 0) { - LOGD("%s, fd=%d", __PRETTY_FUNCTION__, sAkmFD); - close(sAkmFD); - sAkmFD = -1; - } -} - -static void enable_disable(int fd, uint32_t sensors, uint32_t mask) -{ - if (fd<0) return; - short flags; - - if (sensors & SENSORS_ORIENTATION_RAW) { - sensors |= SENSORS_ORIENTATION; - mask |= SENSORS_ORIENTATION; - } else if (mask & SENSORS_ORIENTATION_RAW) { - mask |= SENSORS_ORIENTATION; - } - - if (mask & SENSORS_ORIENTATION) { - flags = (sensors & SENSORS_ORIENTATION) ? 1 : 0; - if (ioctl(fd, ECS_IOCTL_APP_SET_MFLAG, &flags) < 0) { - LOGE("ECS_IOCTL_APP_SET_MFLAG error (%s)", strerror(errno)); - } - } - if (mask & SENSORS_ACCELERATION) { - flags = (sensors & SENSORS_ACCELERATION) ? 1 : 0; - if (ioctl(fd, ECS_IOCTL_APP_SET_AFLAG, &flags) < 0) { - LOGE("ECS_IOCTL_APP_SET_AFLAG error (%s)", strerror(errno)); - } - } - if (mask & SENSORS_TEMPERATURE) { - flags = (sensors & SENSORS_TEMPERATURE) ? 1 : 0; - if (ioctl(fd, ECS_IOCTL_APP_SET_TFLAG, &flags) < 0) { - LOGE("ECS_IOCTL_APP_SET_TFLAG error (%s)", strerror(errno)); - } - } -#ifdef ECS_IOCTL_APP_SET_MVFLAG - if (mask & SENSORS_MAGNETIC_FIELD) { - flags = (sensors & SENSORS_MAGNETIC_FIELD) ? 1 : 0; - if (ioctl(fd, ECS_IOCTL_APP_SET_MVFLAG, &flags) < 0) { - LOGE("ECS_IOCTL_APP_SET_MVFLAG error (%s)", strerror(errno)); - } - } -#endif -} - -static uint32_t read_sensors_state(int fd) -{ - if (fd<0) return 0; - short flags; - uint32_t sensors = 0; - // read the actual value of all sensors - if (!ioctl(fd, ECS_IOCTL_APP_GET_MFLAG, &flags)) { - if (flags) sensors |= SENSORS_ORIENTATION; - else sensors &= ~SENSORS_ORIENTATION; - } - if (!ioctl(fd, ECS_IOCTL_APP_GET_AFLAG, &flags)) { - if (flags) sensors |= SENSORS_ACCELERATION; - else sensors &= ~SENSORS_ACCELERATION; - } - if (!ioctl(fd, ECS_IOCTL_APP_GET_TFLAG, &flags)) { - if (flags) sensors |= SENSORS_TEMPERATURE; - else sensors &= ~SENSORS_TEMPERATURE; - } -#ifdef ECS_IOCTL_APP_SET_MVFLAG - if (!ioctl(fd, ECS_IOCTL_APP_GET_MVFLAG, &flags)) { - if (flags) sensors |= SENSORS_MAGNETIC_FIELD; - else sensors &= ~SENSORS_MAGNETIC_FIELD; - } -#endif - return sensors; -} - -/*****************************************************************************/ - -uint32_t sensors_control_init() -{ - return SUPPORTED_SENSORS; -} - -int sensors_control_open() -{ - return open_input(); -} - -uint32_t sensors_control_activate(uint32_t sensors, uint32_t mask) -{ - mask &= SUPPORTED_SENSORS; - uint32_t active = sActiveSensors; - uint32_t new_sensors = (active & ~mask) | (sensors & mask); - uint32_t changed = active ^ new_sensors; - if (changed) { - int fd = open_akm(); - if (fd < 0) return 0; - - if (!active && new_sensors) { - // force all sensors to be updated - changed = SUPPORTED_SENSORS; - } - - enable_disable(fd, new_sensors, changed); - - if (active && !new_sensors) { - // close the driver - close_akm(); - } - sActiveSensors = active = new_sensors; - LOGD("sensors=%08x, real=%08x", - sActiveSensors, read_sensors_state(fd)); - } - return active; -} - -int sensors_control_delay(int32_t ms) -{ -#ifdef ECS_IOCTL_APP_SET_DELAY - if (sAkmFD <= 0) { - return -1; - } - short delay = ms; - if (!ioctl(sAkmFD, ECS_IOCTL_APP_SET_DELAY, &delay)) { - return -errno; - } - return 0; -#else - return -1; -#endif -} - -/*****************************************************************************/ - -#define MAX_NUM_SENSORS 8 -static int sInputFD = -1; -static const int ID_O = 0; -static const int ID_A = 1; -static const int ID_T = 2; -static const int ID_M = 3; -static const int ID_OR = 7; // orientation raw -static sensors_data_t sSensors[MAX_NUM_SENSORS]; -static uint32_t sPendingSensors; - -int sensors_data_open(int fd) -{ - int i; - LMSInit(); - memset(&sSensors, 0, sizeof(sSensors)); - for (i=0 ; i<MAX_NUM_SENSORS ; i++) { - // by default all sensors have high accuracy - // (we do this because we don't get an update if the value doesn't - // change). - sSensors[i].vector.status = SENSOR_STATUS_ACCURACY_HIGH; - } - sPendingSensors = 0; - sInputFD = dup(fd); - LOGD("sensors_data_open: fd = %d", sInputFD); - return 0; -} - -int sensors_data_close() -{ - close(sInputFD); - sInputFD = -1; - return 0; -} - -static int pick_sensor(sensors_data_t* values) -{ - uint32_t mask = SENSORS_MASK; - while(mask) { - uint32_t i = 31 - __builtin_clz(mask); - mask &= ~(1<<i); - if (sPendingSensors & (1<<i)) { - sPendingSensors &= ~(1<<i); - *values = sSensors[i]; - values->sensor = (1<<i); - LOGD_IF(0, "%d [%f, %f, %f]", (1<<i), - values->vector.x, - values->vector.y, - values->vector.z); - return (1<<i); - } - } - LOGE("No sensor to return!!! sPendingSensors=%08x", sPendingSensors); - // we may end-up in a busy loop, slow things down, just in case. - usleep(100000); - return -1; -} - -int sensors_data_poll(sensors_data_t* values, uint32_t sensors_of_interest) -{ - struct input_event event; - int nread; - int64_t t; - - int fd = sInputFD; - if (fd <= 0) - return -1; - - // there are pending sensors, returns them now... - if (sPendingSensors) { - return pick_sensor(values); - } - - uint32_t new_sensors = 0; - struct pollfd fds; - fds.fd = fd; - fds.events = POLLIN; - fds.revents = 0; - - // wait until we get a complete event for an enabled sensor - while (1) { - nread = 0; - if (sensors_of_interest & SENSORS_ORIENTATION) { - /* We do some special processing if the orientation sensor is - * activated. In particular the yaw value is filtered with a - * LMS filter. Since the kernel only sends an event when the - * value changes, we need to wake up at regular intervals to - * generate an output value (the output value may not be - * constant when the input value is constant) - */ - int err = poll(&fds, 1, SENSORS_TIMEOUT_MS); - if (err == 0) { - struct timespec time; - time.tv_sec = time.tv_nsec = 0; - clock_gettime(CLOCK_MONOTONIC, &time); - - /* generate an output value */ - t = time.tv_sec*1000000000LL+time.tv_nsec; - new_sensors |= SENSORS_ORIENTATION; - sSensors[ID_O].orientation.yaw = - LMSFilter(t, sSensors[ID_O].orientation.yaw); - - /* generate a fake sensors event */ - event.type = EV_SYN; - event.time.tv_sec = time.tv_sec; - event.time.tv_usec = time.tv_nsec/1000; - nread = sizeof(event); - } - } - if (nread == 0) { - /* read the next event */ - nread = read(fd, &event, sizeof(event)); - } - if (nread == sizeof(event)) { - uint32_t v; - if (event.type == EV_ABS) { - //LOGD("type: %d code: %d value: %-5d time: %ds", - // event.type, event.code, event.value, - // (int)event.time.tv_sec); - switch (event.code) { - - case EVENT_TYPE_ACCEL_X: - new_sensors |= SENSORS_ACCELERATION; - sSensors[ID_A].acceleration.x = event.value * CONVERT_A_X; - break; - case EVENT_TYPE_ACCEL_Y: - new_sensors |= SENSORS_ACCELERATION; - sSensors[ID_A].acceleration.y = event.value * CONVERT_A_Y; - break; - case EVENT_TYPE_ACCEL_Z: - new_sensors |= SENSORS_ACCELERATION; - sSensors[ID_A].acceleration.z = event.value * CONVERT_A_Z; - break; - - case EVENT_TYPE_MAGV_X: - new_sensors |= SENSORS_MAGNETIC_FIELD; - sSensors[ID_M].magnetic.x = event.value * CONVERT_M_X; - break; - case EVENT_TYPE_MAGV_Y: - new_sensors |= SENSORS_MAGNETIC_FIELD; - sSensors[ID_M].magnetic.y = event.value * CONVERT_M_Y; - break; - case EVENT_TYPE_MAGV_Z: - new_sensors |= SENSORS_MAGNETIC_FIELD; - sSensors[ID_M].magnetic.z = event.value * CONVERT_M_Z; - break; - - case EVENT_TYPE_YAW: - new_sensors |= SENSORS_ORIENTATION | SENSORS_ORIENTATION_RAW; - t = event.time.tv_sec*1000000000LL + - event.time.tv_usec*1000; - sSensors[ID_O].orientation.yaw = - (sensors_of_interest & SENSORS_ORIENTATION) ? - LMSFilter(t, event.value) : event.value; - sSensors[ID_OR].orientation.yaw = event.value; - break; - case EVENT_TYPE_PITCH: - new_sensors |= SENSORS_ORIENTATION | SENSORS_ORIENTATION_RAW; - sSensors[ID_O].orientation.pitch = event.value; - sSensors[ID_OR].orientation.pitch = event.value; - break; - case EVENT_TYPE_ROLL: - new_sensors |= SENSORS_ORIENTATION | SENSORS_ORIENTATION_RAW; - sSensors[ID_O].orientation.roll = event.value; - sSensors[ID_OR].orientation.roll = event.value; - break; - - case EVENT_TYPE_TEMPERATURE: - new_sensors |= SENSORS_TEMPERATURE; - sSensors[ID_T].temperature = event.value; - break; - - case EVENT_TYPE_STEP_COUNT: - // step count (only reported in MODE_FFD) - // we do nothing with it for now. - break; - case EVENT_TYPE_ACCEL_STATUS: - // accuracy of the calibration (never returned!) - //LOGD("G-Sensor status %d", event.value); - break; - case EVENT_TYPE_ORIENT_STATUS: - // accuracy of the calibration - v = (uint32_t)(event.value & SENSOR_STATE_MASK); - LOGD_IF(sSensors[ID_O].orientation.status != (uint8_t)v, - "M-Sensor status %d", v); - sSensors[ID_O].orientation.status = (uint8_t)v; - sSensors[ID_OR].orientation.status = (uint8_t)v; - break; - } - } else if (event.type == EV_SYN) { - if (new_sensors) { - sPendingSensors = new_sensors; - int64_t t = event.time.tv_sec*1000000000LL + - event.time.tv_usec*1000; - while (new_sensors) { - uint32_t i = 31 - __builtin_clz(new_sensors); - new_sensors &= ~(1<<i); - sSensors[i].time = t; - } - return pick_sensor(values); - } - } - } - } -} - -uint32_t sensors_data_get_sensors() { - return SUPPORTED_SENSORS; -} - diff --git a/tests/gpstest/Android.mk b/tests/gpstest/Android.mk new file mode 100644 index 0000000..6d638b3 --- /dev/null +++ b/tests/gpstest/Android.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + + +LOCAL_SRC_FILES:= gpstest.cpp + +LOCAL_CFLAGS:= -fno-short-enums + +LOCAL_SHARED_LIBRARIES:= libhardware + +LOCAL_C_INCLUDES:= \ + include/hardware + +LOCAL_MODULE:= gpstest + +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) + +LOCAL_MODULE_TAGS:= tests development + +include $(BUILD_EXECUTABLE) diff --git a/tests/gpstest/gpstest.cpp b/tests/gpstest/gpstest.cpp new file mode 100644 index 0000000..79f081d --- /dev/null +++ b/tests/gpstest/gpstest.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +extern "C" size_t dlmalloc_footprint(); + +#include "hardware/gps.h" + +static const GpsInterface* sGpsInterface = NULL; + +static bool sDone = false; +static int sFixes = 0; +static int sMaxFixes = 0; +static int sStatus = GPS_STATUS_ENGINE_OFF; + +static void location_callback(GpsLocation* location) +{ + printf("Got Fix: latitude: %lf longitude: %lf altitude: %.1lf\n", + location->latitude, location->longitude, location->altitude); + sFixes++; + if (sMaxFixes > 0 && sFixes >= sMaxFixes) { + sDone = true; + } +} + +static void status_callback(GpsStatus* status) +{ + switch (status->status) { + case GPS_STATUS_NONE: + printf("status: GPS_STATUS_NONE\n"); + break; + case GPS_STATUS_SESSION_BEGIN: + printf("status: GPS_STATUS_SESSION_BEGIN\n"); + break; + case GPS_STATUS_SESSION_END: + printf("status: GPS_STATUS_SESSION_END\n"); + break; + case GPS_STATUS_ENGINE_ON: + printf("status: GPS_STATUS_ENGINE_ON\n"); + break; + case GPS_STATUS_ENGINE_OFF: + printf("status: GPS_STATUS_ENGINE_OFF\n"); + break; + default: + printf("unknown status: %d\n", status->status); + break; + } + + sStatus = status->status; +} + +static void sv_status_callback(GpsSvStatus* sv_status) +{ + if (sv_status->num_svs > 0) { + for (int i = 0; i < sv_status->num_svs; i++) { + printf("SV: %2d SNR: %.1f Elev: %.1f Azim: %.1f %s %s\n", sv_status->sv_list[i].prn, + sv_status->sv_list[i].snr, sv_status->sv_list[i].elevation, + sv_status->sv_list[i].azimuth, + ((sv_status->ephemeris_mask & (1 << (sv_status->sv_list[i].prn - 1))) ? "E" : " "), + ((sv_status->almanac_mask & (1 << (sv_status->sv_list[i].prn - 1))) ? "A" : " ") + ); + } + printf("\n"); + } +} + +GpsCallbacks sCallbacks = { + location_callback, + status_callback, + sv_status_callback, +}; + +int main(int argc, char *argv[]) +{ + size_t initial = dlmalloc_footprint(); + + if (argc >= 2) { + sMaxFixes = atoi(argv[1]); + printf("max fixes: %d\n", sMaxFixes); + } + + sGpsInterface = gps_get_interface(); + if (!sGpsInterface) { + fprintf(stderr, "could not get gps interface\n"); + return -1; + } + + int err = sGpsInterface->init(&sCallbacks); + if (err) { + fprintf(stderr, "gps_init failed %d\n", err); + return err; + } + + sGpsInterface->start(); + + while (!sDone) { + sleep(1); + } + + sGpsInterface->stop(); + + printf("waiting for GPS to shut down\n"); + while (sStatus != GPS_STATUS_ENGINE_OFF) { + sleep(1); + } + + sGpsInterface->cleanup(); + + size_t final = dlmalloc_footprint(); + fprintf(stderr, "KO: initial == %d, final == %d\n", initial, final ); + + return 0; +} diff --git a/vibrator/vibrator.c b/vibrator/vibrator.c index fcea21c..7d7bfea 100644 --- a/vibrator/vibrator.c +++ b/vibrator/vibrator.c @@ -1,4 +1,20 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <hardware/vibrator.h> +#include "qemu.h" #include <stdio.h> #include <unistd.h> @@ -12,6 +28,12 @@ static int sendit(int timeout_ms) int nwr, ret, fd; char value[20]; +#ifdef QEMU_HARDWARE + if (qemu_check()) { + return qemu_control_command( "vibrator:%d", timeout_ms ); + } +#endif + fd = open(THE_DEVICE, O_RDWR); if(fd < 0) return errno; diff --git a/wifi/wifi.c b/wifi/wifi.c index 68b1a1e..76cbdc9 100644 --- a/wifi/wifi.c +++ b/wifi/wifi.c @@ -131,6 +131,7 @@ static int check_driver_loaded() { */ if ((proc = fopen(MODULE_FILE, "r")) == NULL) { LOGW("Could not open %s: %s", MODULE_FILE, strerror(errno)); + property_set(DRIVER_PROP_NAME, "unloaded"); return 0; } while ((fgets(line, sizeof(line), proc)) != NULL) { @@ -147,21 +148,25 @@ static int check_driver_loaded() { int wifi_load_driver() { char driver_status[PROPERTY_VALUE_MAX]; - int count = 40; /* wait at most 20 seconds for completion */ + int count = 100; /* wait at most 20 seconds for completion */ if (check_driver_loaded()) { return 0; } - insmod(DRIVER_MODULE_PATH); + + if (insmod(DRIVER_MODULE_PATH) < 0) + return -1; + property_set("ctl.start", FIRMWARE_LOADER); + sched_yield(); while (count-- > 0) { - usleep(500000); if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) { if (strcmp(driver_status, "ok") == 0) return 0; else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) return -1; } + usleep(200000); } property_set(DRIVER_PROP_NAME, "timeout"); return -1; @@ -169,10 +174,18 @@ int wifi_load_driver() int wifi_unload_driver() { + int count = 20; /* wait at most 10 seconds for completion */ + if (rmmod(DRIVER_MODULE_NAME) == 0) { - usleep(1000000); - property_set(DRIVER_PROP_NAME, "unloaded"); - return 0; + while (count-- > 0) { + if (!check_driver_loaded()) + break; + usleep(500000); + } + if (count) { + return 0; + } + return -1; } else return -1; } @@ -182,20 +195,21 @@ static int control_supplicant(int startIt) char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; const char *ctrl_prop = (startIt ? "ctl.start" : "ctl.stop"); const char *desired_status = (startIt ? "running" : "stopped"); - int count = 20; /* wait at most 20 seconds for completion */ + int count = 200; /* wait at most 20 seconds for completion */ if (property_get(SUPP_PROP_NAME, supp_status, NULL) && strcmp(supp_status, desired_status) == 0) { return 0; /* supplicant already running */ } property_set(ctrl_prop, SUPPLICANT_NAME); + sched_yield(); while (count-- > 0) { - usleep(1000000); if (property_get(SUPP_PROP_NAME, supp_status, NULL)) { if (strcmp(supp_status, desired_status) == 0) return 0; } + usleep(100000); } return -1; } |