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 30char *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 49bool SamsungSensorBase::handleEvent(input_event const * event) { 50 return true; 51} 52 53int SamsungSensorBase::handleEnable(int en) { 54 return 0; 55} 56 57SamsungSensorBase::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 ALOGE("%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 ALOGE("%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 90SamsungSensorBase::~SamsungSensorBase() { 91 if (mEnabled) { 92 enable(0, 0); 93 } 94 delete[] mInputSysfsEnable; 95 delete[] mInputSysfsPollDelay; 96} 97 98int 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 } 117cleanup: 118 pthread_mutex_unlock(&mLock); 119 return err; 120} 121 122int 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); 136done: 137 pthread_mutex_unlock(&mLock); 138 return result; 139} 140 141int 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 174done: 175 pthread_mutex_unlock(&mLock); 176 return numEventReceived; 177 178} 179