OSDN Git Service

libsensors: Import OTC sensor HAL for HSB and adapt to Android KK
[android-x86/hardware-intel-libsensors.git] / SensorInputDev.cpp
1 /*
2  * Copyright (C) 2010-2012 Intel Corporation
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 #include <dirent.h>
17 #include <fcntl.h>
18 #include <linux/input.h>
19 #include <cutils/log.h>
20
21 #include "SensorInputDev.h"
22
23 SensorInputDev::SensorInputDev(std::string dev)
24     : SensorBase(),
25     mInputReader(4)
26 {
27     findInputDev(dev, mDevPath);
28 }
29
30 int SensorInputDev::readEvents(sensors_event_t* data, int count)
31 {
32     if (count < 1)
33         return -EINVAL;
34
35     if (mHasPendingEvent) {
36         mHasPendingEvent = false;
37         mPendingEvent.timestamp = getTimestamp();
38         *data = mPendingEvent;
39         return 1;
40     }
41
42     if (mFd < 0)
43         return -EBADF;
44
45     ssize_t n = mInputReader.fill(mFd);
46     if (n < 0)
47         return n;
48
49     int numEventReceived = 0;
50     input_event const* event;
51
52 #if FETCH_FULL_EVENT_BEFORE_RETURN
53 again:
54 #endif
55     while (count && mInputReader.readEvent(&event)) {
56         /* do sensor specific stuff */
57         processEvent(*event);
58
59         if (event->type == EV_SYN) {
60             mPendingEvent.timestamp = timevalToNano(event->time);
61             if (mEnabled) {
62                 *data++ = mPendingEvent;
63                 count--;
64                 numEventReceived++;
65             }
66             ALOGV("%s:%s:, in type = EV_SYN, after, count = %d, numEventReceived = %d, mEnabled = %d",
67                  __func__, mDevPath.c_str(), count, numEventReceived, mEnabled);
68         }
69
70         mInputReader.next();
71     }
72
73 #if FETCH_FULL_EVENT_BEFORE_RETURN
74     /* if we didn't read a complete event, see if we can fill and
75        try again instead of returning with nothing and redoing poll. */
76     if (numEventReceived == 0 && mEnabled == 1) {
77         n = mInputReader.fill(mFd);
78         if (n)
79             goto again;
80     }
81 #endif
82
83     return numEventReceived;
84 }
85
86 bool SensorInputDev::findInputDev(const std::string &inputName,
87                                   std::string &foundPath)
88 {
89     bool found = false;
90     std::string dev = "/dev/input";
91     DIR *dir = opendir(dev.c_str());
92     if (!dir)
93         return false;
94
95     struct dirent *de;
96     while ((de = readdir(dir))) {
97         if(de->d_name[0] == '.' &&
98            (de->d_name[1] == '\0' ||
99             (de->d_name[1] == '.' && de->d_name[2] == '\0')))
100             continue;
101
102         int fd = ::open((dev + "/" + de->d_name).c_str(), O_RDONLY);
103         if (fd < 0)
104             continue;
105
106         ALOGV("%s: probing path %s against %s", __func__, (dev + "/" + de->d_name).c_str(), inputName.c_str());
107         char readName[80];
108         if (ioctl(fd, EVIOCGNAME(sizeof(readName) - 1), &readName) < 1)
109                 readName[0] = '\0';
110
111         ::close(fd);
112
113         if (inputName.compare(readName) == 0) {
114             foundPath = (dev + "/" + de->d_name);
115             found = true;
116             ALOGV("%s: found %s", __func__, foundPath.c_str());
117             break;
118         }
119     }
120
121     closedir(dir);
122
123     ALOGE_IF(!found, "couldn't find '%s' input device", inputName.c_str());
124
125     return found;
126 }