• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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