#include <cerrno>
#include <cstdlib>
#include <cstring>
+#include <cinttypes>
#include <sys/stat.h>
#include <poll.h>
#include <fcntl.h>
const int ID_ACCELERATION = (SENSORS_HANDLE_BASE + 0);
template <typename T> struct SensorFd : T {
- SensorFd(const struct hw_module_t *module, struct hw_device_t **device);
+ SensorFd(const struct hw_module_t *module);
};
-template <typename T> SensorFd<T>::SensorFd(const struct hw_module_t *module, struct hw_device_t **device)
+template <typename T> SensorFd<T>::SensorFd(const struct hw_module_t *module)
{
+ memset(this, 0, sizeof(*this));
this->common.tag = HARDWARE_DEVICE_TAG;
- this->common.version = 0;
+ this->common.version = SENSORS_DEVICE_API_VERSION_1_3;
this->common.module = const_cast<struct hw_module_t *>(module);
- *device = &this->common;
- ALOGD("%s: module=%p dev=%p", __FUNCTION__, module, *device);
}
-struct SensorPollContext : SensorFd<sensors_poll_device_t> {
+struct SensorPollContext : SensorFd<sensors_poll_device_1> {
public:
SensorPollContext(const struct hw_module_t *module, struct hw_device_t **device);
~SensorPollContext();
+ bool isValid() const { return (pfd.fd >= 0); }
private:
static int poll_close(struct hw_device_t *dev);
static int poll_activate(struct sensors_poll_device_t *dev, int handle, int enabled);
static int poll_setDelay(struct sensors_poll_device_t *dev, int handle, int64_t ns);
static int poll_poll(struct sensors_poll_device_t *dev, sensors_event_t *data, int count);
+ static int poll_batch(struct sensors_poll_device_1* dev, int sensor_handle, int flags, int64_t sampling_period_ns, int64_t max_report_latency_ns);
+ static int poll_flush(struct sensors_poll_device_1* dev, int sensor_handle);
int doPoll(sensors_event_t *data, int count);
bool enabled;
int rotation;
- struct timespec delay;
+ int64_t sampling_period_ns;
struct pollfd pfd;
sensors_event_t orients[4];
KbdSensorKeys *ktype;
};
+void parse_kbd_keys_from_prop(char *prop, KbdSensorKeys *ktype)
+{
+ strlcpy(ktype->name, strsep(&prop, ","), sizeof(ktype->name));
+ sscanf(prop, "%d,%d,%d,%d,%d,%d,%d,%d", ktype->keys,
+ ktype->keys + 1, ktype->keys + 2, ktype->keys + 3, ktype->keys + 4, ktype->keys + 5, ktype->keys + 6, ktype->keys + 7);
+ ALOGD("[%s]: %d,%d,%d,...", ktype->name, ktype->keys[0], ktype->keys[1], ktype->keys[2]);
+}
+
SensorPollContext::SensorPollContext(const struct hw_module_t *module, struct hw_device_t **device)
- : SensorFd<sensors_poll_device_t>(module, device), enabled(false), rotation(ROT_0), ktype(KeysType)
+ : SensorFd<sensors_poll_device_1>(module), enabled(false), rotation(ROT_0), ktype(KeysType)
{
common.close = poll_close;
activate = poll_activate;
setDelay = poll_setDelay;
poll = poll_poll;
+ batch = poll_batch;
+ flush = poll_flush;
int &fd = pfd.fd;
+ fd = -1;
const char *dirname = "/dev/input";
char prop[PROPERTY_VALUE_MAX];
if (property_get("hal.sensors.kbd.keys", prop, 0))
- sscanf(prop, "%s,%d,%d,%d,%d,%d,%d,%d,%d", ktype->name, ktype->keys,
- ktype->keys + 1, ktype->keys + 2, ktype->keys + 3, ktype->keys + 4, ktype->keys + 5, ktype->keys + 6, ktype->keys + 7);
+ parse_kbd_keys_from_prop(prop, ktype);
else if (property_get("hal.sensors.kbd.type", prop, 0))
ktype = &KeysType[atoi(prop)];
else
close(fd);
fd = -1;
}
- ALOGI_IF(fd >= 0, "Open %s ok, fd=%d", name, fd);
closedir(dir);
+ if (fd < 0) {
+ ALOGW("could not find any kbdsensor device");
+ return;
+ }
+ *device = &common;
+ ALOGI("Open %s ok, fd=%d", name, fd);
}
pfd.events = POLLIN;
orients[ROT_270].acceleration.y = 0.0;
orients[ROT_270].acceleration.z = -sin_angle;
- delay.tv_sec = 0;
- delay.tv_nsec = 200000000L;
-
- ALOGD("%s: dev=%p fd=%d", __FUNCTION__, this, fd);
+ ALOGD("%s: module=%p dev=%p fd=%d", __FUNCTION__, module, this, fd);
}
SensorPollContext::~SensorPollContext()
int SensorPollContext::poll_setDelay(struct sensors_poll_device_t *dev, int handle, int64_t ns)
{
- ALOGD("%s: dev=%p delay-ns=%lld", __FUNCTION__, dev, ns);
- return 0;
+ ALOGD("%s: dev=%p handle=%d ns=%" PRId64, __FUNCTION__, dev, handle, ns);
+ SensorPollContext *ctx = reinterpret_cast<SensorPollContext *>(dev);
+ ctx->sampling_period_ns = ns;
+ return EXIT_SUCCESS;
}
int SensorPollContext::poll_poll(struct sensors_poll_device_t *dev, sensors_event_t *data, int count)
return ctx->doPoll(data, count);
}
+int SensorPollContext::poll_batch(struct sensors_poll_device_1* dev, int sensor_handle, int flags, int64_t sampling_period_ns, int64_t max_report_latency_ns)
+{
+ ALOGD("%s: dev=%p sensor_handle=%d flags=%d sampling_period_ns=%" PRId64 " max_report_latency_ns=%" PRId64,
+ __FUNCTION__, dev, sensor_handle, flags, sampling_period_ns, max_report_latency_ns);
+ return poll_setDelay(&dev->v0, sensor_handle, sampling_period_ns);
+}
+
+int SensorPollContext::poll_flush(struct sensors_poll_device_1* dev, int sensor_handle)
+{
+ ALOGD("%s: dev=%p sensor_handle=%d", __FUNCTION__, dev, sensor_handle);
+ return EXIT_SUCCESS;
+}
+
int SensorPollContext::doPoll(sensors_event_t *data, int count)
{
- nanosleep(&delay, 0);
+ if (!isValid())
+ return 0;
+
int *keys = ktype->keys;
while (int pollres = ::poll(&pfd, 1, -1)) {
if (pollres < 0) {
struct input_event iev;
size_t res = ::read(pfd.fd, &iev, sizeof(iev));
if (res < sizeof(iev)) {
- ALOGW("insufficient input data(%d)? fd=%d", res, pfd.fd);
+ ALOGW("insufficient input data(%zu)? fd=%d", res, pfd.fd);
continue;
}
ALOGV("type=%d scancode=%d value=%d from fd=%d", iev.type, iev.code, iev.value, pfd.fd);
rotation = ROT_0;
else
rotation++;
- }
+ }
if (iev.code == keys[2] && iev.value) {
if (rotation == ROT_0)
rotation = ROT_270;
else
rotation--;
- }
+ }
break;
} else if (iev.type == EV_SW && iev.code == SW_TABLET_MODE) {
if (!iev.value)
}
int cnt;
- struct timespec t;
+ struct timespec t = { 0, 0 };
data[0] = orients[rotation];
- t.tv_sec = t.tv_nsec = 0;
clock_gettime(CLOCK_MONOTONIC, &t);
data[0].timestamp = int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec;
- for (cnt = 1; cnt < keys[7] && cnt < count; ++cnt) {
+ struct timespec delay = { 0, static_cast<long>(sampling_period_ns) };
+ for (cnt = 1; !nanosleep(&delay, 0) && cnt < keys[7] && cnt < count; ++cnt) {
data[cnt] = data[cnt - 1];
- data[cnt].timestamp += delay.tv_nsec;
- nanosleep(&delay, 0);
+ data[cnt].timestamp += sampling_period_ns;
}
ALOGV("%s: dev=%p fd=%d rotation=%d cnt=%d", __FUNCTION__, this, pfd.fd, rotation * 90, cnt);
return cnt;
static int open_kbd_sensor(const struct hw_module_t *module, const char *id, struct hw_device_t **device)
{
ALOGD("%s: id=%s", __FUNCTION__, id);
- return new SensorPollContext(module, device) ? 0 : -EINVAL;
+ SensorPollContext *ctx = new SensorPollContext(module, device);
+ return (ctx && ctx->isValid()) ? 0 : -EINVAL;
}
static struct sensor_t sSensorListInit[] = {
{
- name: "Kbd Orientation Sensor",
- vendor: "Android-x86 Open Source Project",
- version: 1,
- handle: ID_ACCELERATION,
- type: SENSOR_TYPE_ACCELEROMETER,
- maxRange: 2.8f,
- resolution: 1.0f/4032.0f,
- power: 3.0f,
- minDelay: 0,
- fifoReservedEventCount: 0,
- fifoMaxEventCount: 0,
- reserved: { }
+ .name = "Kbd Orientation Sensor",
+ .vendor = "Android-x86 Open Source Project",
+ .version = 2,
+ .handle = ID_ACCELERATION,
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .maxRange = 2.8f,
+ .resolution = 1.0f/4032.0f,
+ .power = 3.0f,
+ .minDelay = 0,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 0,
+ .stringType = 0,
+ .requiredPermission = 0,
+ .maxDelay = 2000,
+ .flags = SENSOR_FLAG_CONTINUOUS_MODE,
+ .reserved = { }
}
};
-static int sensors_get_sensors_list(struct sensors_module_t *module, struct sensor_t const **list)
+static int sensors_get_sensors_list(struct sensors_module_t *, struct sensor_t const **list)
{
*list = sSensorListInit;
return sizeof(sSensorListInit) / sizeof(struct sensor_t);
}
static struct hw_module_methods_t sensors_methods = {
- open: open_kbd_sensor
+ .open = open_kbd_sensor
};
struct sensors_module_t HAL_MODULE_INFO_SYM = {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: 2,
- version_minor: 3,
- id: SENSORS_HARDWARE_MODULE_ID,
- name: "Kbd Orientation Sensor",
- author: "Chih-Wei Huang",
- methods: &sensors_methods,
- dso: 0,
- reserved: { }
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = 2,
+ .hal_api_version = 0,
+ .id = SENSORS_HARDWARE_MODULE_ID,
+ .name = "Kbd Orientation Sensor",
+ .author = "Chih-Wei Huang",
+ .methods = &sensors_methods,
+ .dso = 0,
+ .reserved = { }
},
- get_sensors_list: sensors_get_sensors_list
+ .get_sensors_list = sensors_get_sensors_list
};