| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2010 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 |  */ | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 16 |  | 
 | 17 | #define LOG_TAG "Sensors" | 
 | 18 |  | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 19 | #include <stdint.h> | 
 | 20 | #include <sys/types.h> | 
 | 21 |  | 
 | 22 | #include <utils/Errors.h> | 
 | 23 | #include <utils/RefBase.h> | 
| Jeff Brown | 59abe7e | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 24 | #include <utils/Looper.h> | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 25 |  | 
 | 26 | #include <gui/Sensor.h> | 
 | 27 | #include <gui/SensorChannel.h> | 
 | 28 | #include <gui/SensorEventQueue.h> | 
 | 29 | #include <gui/ISensorEventConnection.h> | 
 | 30 |  | 
 | 31 | #include <android/sensor.h> | 
 | 32 |  | 
 | 33 | // ---------------------------------------------------------------------------- | 
 | 34 | namespace android { | 
 | 35 | // ---------------------------------------------------------------------------- | 
 | 36 |  | 
 | 37 | SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection) | 
 | 38 |     : mSensorEventConnection(connection) | 
 | 39 | { | 
 | 40 | } | 
 | 41 |  | 
 | 42 | SensorEventQueue::~SensorEventQueue() | 
 | 43 | { | 
 | 44 | } | 
 | 45 |  | 
 | 46 | void SensorEventQueue::onFirstRef() | 
 | 47 | { | 
 | 48 |     mSensorChannel = mSensorEventConnection->getSensorChannel(); | 
 | 49 | } | 
 | 50 |  | 
 | 51 | int SensorEventQueue::getFd() const | 
 | 52 | { | 
 | 53 |     return mSensorChannel->getFd(); | 
 | 54 | } | 
 | 55 |  | 
 | 56 | ssize_t SensorEventQueue::write(ASensorEvent const* events, size_t numEvents) | 
 | 57 | { | 
 | 58 |     ssize_t size = mSensorChannel->write(events, numEvents * sizeof(events[0])); | 
 | 59 |     if (size >= 0) { | 
 | 60 |         if (size % sizeof(events[0])) { | 
 | 61 |             // partial write!!! should never happen. | 
 | 62 |             return -EINVAL; | 
 | 63 |         } | 
 | 64 |         // returns number of events written | 
 | 65 |         size /= sizeof(events[0]); | 
 | 66 |     } | 
 | 67 |     return size; | 
 | 68 | } | 
 | 69 |  | 
 | 70 | ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) | 
 | 71 | { | 
 | 72 |     ssize_t size = mSensorChannel->read(events, numEvents*sizeof(events[0])); | 
| Steve Block | 11862d6 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 73 |     ALOGE_IF(size<0 && size!=-EAGAIN, | 
| Mathias Agopian | aeda9af | 2010-09-16 17:04:16 -0700 | [diff] [blame] | 74 |             "SensorChannel::read error (%s)", strerror(-size)); | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 75 |     if (size >= 0) { | 
 | 76 |         if (size % sizeof(events[0])) { | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 77 |             // partial read!!! should never happen. | 
| Steve Block | 11862d6 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 78 |             ALOGE("SensorEventQueue partial read (event-size=%u, read=%d)", | 
| Mathias Agopian | aeda9af | 2010-09-16 17:04:16 -0700 | [diff] [blame] | 79 |                     sizeof(events[0]), int(size)); | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 80 |             return -EINVAL; | 
 | 81 |         } | 
 | 82 |         // returns number of events read | 
 | 83 |         size /= sizeof(events[0]); | 
 | 84 |     } | 
 | 85 |     return size; | 
 | 86 | } | 
 | 87 |  | 
| Jeff Brown | 59abe7e | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 88 | sp<Looper> SensorEventQueue::getLooper() const | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 89 | { | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 90 |     Mutex::Autolock _l(mLock); | 
| Jeff Brown | 59abe7e | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 91 |     if (mLooper == 0) { | 
 | 92 |         mLooper = new Looper(true); | 
 | 93 |         mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, NULL, NULL); | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 94 |     } | 
| Jeff Brown | 59abe7e | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 95 |     return mLooper; | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 96 | } | 
 | 97 |  | 
 | 98 | status_t SensorEventQueue::waitForEvent() const | 
 | 99 | { | 
 | 100 |     const int fd = getFd(); | 
| Jeff Brown | 59abe7e | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 101 |     sp<Looper> looper(getLooper()); | 
| Mathias Agopian | aeda9af | 2010-09-16 17:04:16 -0700 | [diff] [blame] | 102 |  | 
 | 103 |     int32_t result; | 
 | 104 |     do { | 
 | 105 |         result = looper->pollOnce(-1); | 
 | 106 |         if (result == ALOOPER_EVENT_ERROR) { | 
| Steve Block | 11862d6 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 107 |             ALOGE("SensorChannel::waitForEvent error (errno=%d)", errno); | 
| Mathias Agopian | aeda9af | 2010-09-16 17:04:16 -0700 | [diff] [blame] | 108 |             result = -EPIPE; // unknown error, so we make up one | 
 | 109 |             break; | 
 | 110 |         } | 
 | 111 |     } while (result != fd); | 
 | 112 |  | 
| Mathias Agopian | 2ffb247 | 2010-09-16 21:41:13 -0700 | [diff] [blame] | 113 |     return  (result == fd) ? status_t(NO_ERROR) : result; | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 114 | } | 
 | 115 |  | 
 | 116 | status_t SensorEventQueue::wake() const | 
 | 117 | { | 
| Jeff Brown | 59abe7e | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 118 |     sp<Looper> looper(getLooper()); | 
 | 119 |     looper->wake(); | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 120 |     return NO_ERROR; | 
 | 121 | } | 
 | 122 |  | 
 | 123 | status_t SensorEventQueue::enableSensor(Sensor const* sensor) const { | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 124 |     return mSensorEventConnection->enableDisable(sensor->getHandle(), true); | 
 | 125 | } | 
 | 126 |  | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 127 | status_t SensorEventQueue::disableSensor(Sensor const* sensor) const { | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 128 |     return mSensorEventConnection->enableDisable(sensor->getHandle(), false); | 
 | 129 | } | 
 | 130 |  | 
| Mathias Agopian | a48bcf6 | 2010-07-29 16:51:38 -0700 | [diff] [blame] | 131 | status_t SensorEventQueue::enableSensor(int32_t handle, int32_t us) const { | 
| Mathias Agopian | e3c8234 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 132 |     status_t err = mSensorEventConnection->enableDisable(handle, true); | 
 | 133 |     if (err == NO_ERROR) { | 
| Mathias Agopian | a48bcf6 | 2010-07-29 16:51:38 -0700 | [diff] [blame] | 134 |         mSensorEventConnection->setEventRate(handle, us2ns(us)); | 
| Mathias Agopian | e3c8234 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 135 |     } | 
 | 136 |     return err; | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 137 | } | 
 | 138 |  | 
 | 139 | status_t SensorEventQueue::disableSensor(int32_t handle) const { | 
 | 140 |     return mSensorEventConnection->enableDisable(handle, false); | 
 | 141 | } | 
 | 142 |  | 
 | 143 | status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const { | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 144 |     return mSensorEventConnection->setEventRate(sensor->getHandle(), ns); | 
 | 145 | } | 
 | 146 |  | 
 | 147 | // ---------------------------------------------------------------------------- | 
 | 148 | }; // namespace android | 
 | 149 |  |