1 /*
2 * Copyright (C) 2011 Samsung
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 <fcntl.h>
22 #include <unistd.h>
23 #include <dirent.h>
24 #include <sys/select.h>
25 #include <cutils/log.h>
26 #include <pthread.h>
27
28 #include "SamsungSensorBase.h"
29
makeSysfsName(const char * input_name,const char * file_name)30 char *SamsungSensorBase::makeSysfsName(const char *input_name,
31 const char *file_name) {
32 char *name;
33 int length = strlen("/sys/class/input/") +
34 strlen(input_name) +
35 strlen("/device/") +
36 strlen(file_name);
37
38 name = new char[length + 1];
39 if (name) {
40 strcpy(name, "/sys/class/input/");
41 strcat(name, input_name);
42 strcat(name, "/device/");
43 strcat(name, file_name);
44 }
45
46 return name;
47 }
48
handleEvent(input_event const * event)49 bool SamsungSensorBase::handleEvent(input_event const * event) {
50 return true;
51 }
52
handleEnable(int en)53 int SamsungSensorBase::handleEnable(int en) {
54 return 0;
55 }
56
SamsungSensorBase(const char * dev_name,const char * data_name,int sensor_code)57 SamsungSensorBase::SamsungSensorBase(const char *dev_name,
58 const char *data_name,
59 int sensor_code)
60 : SensorBase(dev_name, data_name),
61 mEnabled(true),
62 mHasPendingEvent(false),
63 mInputReader(4),
64 mSensorCode(sensor_code),
65 mLock(PTHREAD_MUTEX_INITIALIZER)
66 {
67 mPendingEvent.version = sizeof(sensors_event_t);
68 memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
69 if (!data_fd)
70 return;
71 mInputSysfsEnable = makeSysfsName(input_name, "enable");
72 if (!mInputSysfsEnable) {
73 LOGE("%s: unable to allocate mem for %s:enable", __func__,
74 data_name);
75 return;
76 }
77 mInputSysfsPollDelay = makeSysfsName(input_name, "poll_delay");
78 if (!mInputSysfsPollDelay) {
79 LOGE("%s: unable to allocate mem for %s:poll_delay", __func__,
80 data_name);
81 return;
82 }
83
84 int flags = fcntl(data_fd, F_GETFL, 0);
85 fcntl(data_fd, F_SETFL, flags | O_NONBLOCK);
86
87 enable(0, 0);
88 }
89
~SamsungSensorBase()90 SamsungSensorBase::~SamsungSensorBase() {
91 if (mEnabled) {
92 enable(0, 0);
93 }
94 delete[] mInputSysfsEnable;
95 delete[] mInputSysfsPollDelay;
96 }
97
enable(int32_t handle,int en)98 int SamsungSensorBase::enable(int32_t handle, int en)
99 {
100 int err = 0;
101 pthread_mutex_lock(&mLock);
102 if (en != mEnabled) {
103 int fd;
104 fd = open(mInputSysfsEnable, O_RDWR);
105 if (fd >= 0) {
106 err = write(fd, en ? "1" : "0", 2);
107 close(fd);
108 if (err < 0) {
109 goto cleanup;
110 }
111 mEnabled = en;
112 err = handleEnable(en);
113 } else {
114 err = -1;
115 }
116 }
117 cleanup:
118 pthread_mutex_unlock(&mLock);
119 return err;
120 }
121
setDelay(int32_t handle,int64_t ns)122 int SamsungSensorBase::setDelay(int32_t handle, int64_t ns)
123 {
124 int fd;
125 int result = 0;
126 char buf[21];
127 pthread_mutex_lock(&mLock);
128 fd = open(mInputSysfsPollDelay, O_RDWR);
129 if (fd < 0) {
130 result = -1;
131 goto done;
132 }
133 sprintf(buf, "%lld", ns);
134 write(fd, buf, strlen(buf)+1);
135 close(fd);
136 done:
137 pthread_mutex_unlock(&mLock);
138 return result;
139 }
140
readEvents(sensors_event_t * data,int count)141 int SamsungSensorBase::readEvents(sensors_event_t* data, int count)
142 {
143 if (count < 1)
144 return -EINVAL;
145
146 pthread_mutex_lock(&mLock);
147 int numEventReceived = 0;
148
149 if (mHasPendingEvent) {
150 mHasPendingEvent = false;
151 if (mEnabled) {
152 mPendingEvent.timestamp = getTimestamp();
153 *data = mPendingEvent;
154 numEventReceived++;
155 }
156 goto done;
157 }
158
159 input_event const* event;
160 while (count && mInputReader.readEvent(data_fd, &event)) {
161 if (event->type == EV_ABS) {
162 if (event->code == mSensorCode) {
163 if (mEnabled && handleEvent(event)) {
164 mPendingEvent.timestamp = timevalToNano(event->time);
165 *data++ = mPendingEvent;
166 count--;
167 numEventReceived++;
168 }
169 }
170 }
171 mInputReader.next();
172 }
173
174 done:
175 pthread_mutex_unlock(&mLock);
176 return numEventReceived;
177
178 }
179