1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <fcntl.h>
18#include <errno.h>
19#include <math.h>
20#include <poll.h>
21#include <string.h>
22#include <unistd.h>
23#include <dirent.h>
24#include <sys/select.h>
25
26#include <cutils/log.h>
27
28#include <linux/input.h>
29
30#include "SensorBase.h"
31
32/*****************************************************************************/
33
34SensorBase::SensorBase(
35        const char* dev_name,
36        const char* data_name)
37    : dev_name(dev_name), data_name(data_name),
38      dev_fd(-1), data_fd(-1)
39{
40    if (data_name) {
41        data_fd = openInput(data_name);
42    }
43}
44
45SensorBase::~SensorBase() {
46    if (data_fd >= 0) {
47        close(data_fd);
48    }
49    if (dev_fd >= 0) {
50        close(dev_fd);
51    }
52}
53
54int SensorBase::open_device() {
55    if (dev_fd<0 && dev_name) {
56        dev_fd = open(dev_name, O_RDONLY);
57        ALOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno));
58    }
59    return 0;
60}
61
62int SensorBase::close_device() {
63    if (dev_fd >= 0) {
64        close(dev_fd);
65        dev_fd = -1;
66    }
67    return 0;
68}
69
70int SensorBase::write_sys_attribute(
71	const char *path, const char *value, int bytes)
72{
73    int fd, amt;
74
75	fd = open(path, O_WRONLY);
76    if (fd < 0) {
77        ALOGE("SensorBase: write_attr failed to open %s (%s)",
78			path, strerror(errno));
79        return -1;
80	}
81
82    amt = write(fd, value, bytes);
83	amt = ((amt == -1) ? -errno : 0);
84	ALOGE_IF(amt < 0, "SensorBase: write_int failed to write %s (%s)",
85		path, strerror(errno));
86    close(fd);
87	return amt;
88}
89
90int SensorBase::getFd() const {
91    if (!data_name) {
92        return dev_fd;
93    }
94    return data_fd;
95}
96
97int SensorBase::setDelay(int32_t handle, int64_t ns) {
98    return 0;
99}
100
101int64_t SensorBase::getDelay(int32_t handle) {
102    return 0;
103}
104
105bool SensorBase::hasPendingEvents() const {
106    return false;
107}
108
109int64_t SensorBase::getTimestamp() {
110    struct timespec t;
111    t.tv_sec = t.tv_nsec = 0;
112    clock_gettime(CLOCK_MONOTONIC, &t);
113    return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec;
114}
115
116int SensorBase::openInput(const char* inputName) {
117    int fd = -1;
118    const char *dirname = "/dev/input";
119    char devname[PATH_MAX];
120    char *filename;
121    DIR *dir;
122    struct dirent *de;
123    dir = opendir(dirname);
124    if(dir == NULL)
125        return -1;
126    strcpy(devname, dirname);
127    filename = devname + strlen(devname);
128    *filename++ = '/';
129    while((de = readdir(dir))) {
130        if(de->d_name[0] == '.' &&
131                (de->d_name[1] == '\0' ||
132                        (de->d_name[1] == '.' && de->d_name[2] == '\0')))
133            continue;
134        strcpy(filename, de->d_name);
135        fd = open(devname, O_RDONLY);
136        if (fd>=0) {
137            char name[80];
138            if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
139                name[0] = '\0';
140            }
141            if (!strcmp(name, inputName)) {
142                strcpy(input_name, filename);
143                break;
144            } else {
145                close(fd);
146                fd = -1;
147            }
148        }
149    }
150    closedir(dir);
151    ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);
152    return fd;
153}
154