blob: 4438d454c0ecd238d999d4943ddc6299f6e338b4 [file] [log] [blame]
Mathias Agopian589ce852010-07-13 22:21:56 -07001/*
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 Agopiana7352c92010-07-14 23:41:37 -070016
17#define LOG_TAG "Sensors"
18
Mathias Agopian801ea092017-03-06 15:05:04 -080019#include <sensor/SensorEventQueue.h>
Mathias Agopian589ce852010-07-13 22:21:56 -070020
Mathias Agopian801ea092017-03-06 15:05:04 -080021#include <algorithm>
22#include <sys/socket.h>
23
Mathias Agopian589ce852010-07-13 22:21:56 -070024#include <utils/RefBase.h>
Jeff Brown59abe7e2010-09-13 23:17:30 -070025#include <utils/Looper.h>
Mathias Agopian589ce852010-07-13 22:21:56 -070026
Mathias Agopian801ea092017-03-06 15:05:04 -080027#include <sensor/Sensor.h>
28#include <sensor/BitTube.h>
29#include <sensor/ISensorEventConnection.h>
Mathias Agopian589ce852010-07-13 22:21:56 -070030
31#include <android/sensor.h>
Brian Stacke318d6b2019-01-16 15:43:37 -080032#include <hardware/sensors-base.h>
Mathias Agopian589ce852010-07-13 22:21:56 -070033
Dan Stozad723bd72014-11-18 10:24:03 -080034using std::min;
35
Mathias Agopian589ce852010-07-13 22:21:56 -070036// ----------------------------------------------------------------------------
37namespace android {
38// ----------------------------------------------------------------------------
39
40SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
Yi Kongd5e079f2018-07-17 16:08:27 -070041 : mSensorEventConnection(connection), mRecBuffer(nullptr), mAvailable(0), mConsumed(0),
Aravind Akella8a969552014-09-28 17:52:41 -070042 mNumAcksToSend(0) {
Mathias Agopian90ed3e82013-09-09 23:36:25 -070043 mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
Mathias Agopian589ce852010-07-13 22:21:56 -070044}
45
Mathias Agopian90ed3e82013-09-09 23:36:25 -070046SensorEventQueue::~SensorEventQueue() {
47 delete [] mRecBuffer;
Mathias Agopian589ce852010-07-13 22:21:56 -070048}
49
50void SensorEventQueue::onFirstRef()
51{
52 mSensorChannel = mSensorEventConnection->getSensorChannel();
53}
54
55int SensorEventQueue::getFd() const
56{
57 return mSensorChannel->getFd();
58}
59
Mathias Agopian7b5be952012-04-02 17:02:19 -070060
61ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
62 ASensorEvent const* events, size_t numEvents) {
63 return BitTube::sendObjects(tube, events, numEvents);
Mathias Agopian589ce852010-07-13 22:21:56 -070064}
65
Mathias Agopian90ed3e82013-09-09 23:36:25 -070066ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
67 if (mAvailable == 0) {
68 ssize_t err = BitTube::recvObjects(mSensorChannel,
69 mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
70 if (err < 0) {
71 return err;
72 }
Dan Stozad723bd72014-11-18 10:24:03 -080073 mAvailable = static_cast<size_t>(err);
Mathias Agopian90ed3e82013-09-09 23:36:25 -070074 mConsumed = 0;
75 }
Dan Stozad723bd72014-11-18 10:24:03 -080076 size_t count = min(numEvents, mAvailable);
77 memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
Mathias Agopian90ed3e82013-09-09 23:36:25 -070078 mAvailable -= count;
79 mConsumed += count;
Dan Stozad723bd72014-11-18 10:24:03 -080080 return static_cast<ssize_t>(count);
Mathias Agopian589ce852010-07-13 22:21:56 -070081}
82
Jeff Brown59abe7e2010-09-13 23:17:30 -070083sp<Looper> SensorEventQueue::getLooper() const
Mathias Agopian589ce852010-07-13 22:21:56 -070084{
Mathias Agopiana7352c92010-07-14 23:41:37 -070085 Mutex::Autolock _l(mLock);
Yi Kongd5e079f2018-07-17 16:08:27 -070086 if (mLooper == nullptr) {
Jeff Brown59abe7e2010-09-13 23:17:30 -070087 mLooper = new Looper(true);
Yi Kongd5e079f2018-07-17 16:08:27 -070088 mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, nullptr, nullptr);
Mathias Agopiana7352c92010-07-14 23:41:37 -070089 }
Jeff Brown59abe7e2010-09-13 23:17:30 -070090 return mLooper;
Mathias Agopiana7352c92010-07-14 23:41:37 -070091}
92
93status_t SensorEventQueue::waitForEvent() const
94{
95 const int fd = getFd();
Jeff Brown59abe7e2010-09-13 23:17:30 -070096 sp<Looper> looper(getLooper());
Mathias Agopianaeda9af2010-09-16 17:04:16 -070097
Mathias Agopian29267fe2012-05-07 15:20:15 -070098 int events;
Mathias Agopianaeda9af2010-09-16 17:04:16 -070099 int32_t result;
100 do {
Yi Kongd5e079f2018-07-17 16:08:27 -0700101 result = looper->pollOnce(-1, nullptr, &events, nullptr);
Mathias Agopian29267fe2012-05-07 15:20:15 -0700102 if (result == ALOOPER_POLL_ERROR) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000103 ALOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
Mathias Agopianaeda9af2010-09-16 17:04:16 -0700104 result = -EPIPE; // unknown error, so we make up one
105 break;
106 }
Mathias Agopian29267fe2012-05-07 15:20:15 -0700107 if (events & ALOOPER_EVENT_HANGUP) {
108 // the other-side has died
109 ALOGE("SensorEventQueue::waitForEvent error HANGUP");
110 result = -EPIPE; // unknown error, so we make up one
111 break;
112 }
Mathias Agopianaeda9af2010-09-16 17:04:16 -0700113 } while (result != fd);
114
Mathias Agopian2ffb2472010-09-16 21:41:13 -0700115 return (result == fd) ? status_t(NO_ERROR) : result;
Mathias Agopiana7352c92010-07-14 23:41:37 -0700116}
117
118status_t SensorEventQueue::wake() const
119{
Jeff Brown59abe7e2010-09-13 23:17:30 -0700120 sp<Looper> looper(getLooper());
121 looper->wake();
Mathias Agopiana7352c92010-07-14 23:41:37 -0700122 return NO_ERROR;
123}
124
125status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
Peng Xu2f3bf132016-03-16 18:05:35 -0700126 return enableSensor(sensor, SENSOR_DELAY_NORMAL);
127}
128
129status_t SensorEventQueue::enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const {
130 return mSensorEventConnection->enableDisable(sensor->getHandle(), true,
131 us2ns(samplingPeriodUs), 0, 0);
Mathias Agopian589ce852010-07-13 22:21:56 -0700132}
133
Mathias Agopiana7352c92010-07-14 23:41:37 -0700134status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
Peng Xu2f3bf132016-03-16 18:05:35 -0700135 return mSensorEventConnection->enableDisable(sensor->getHandle(), false, 0, 0, 0);
Mathias Agopian589ce852010-07-13 22:21:56 -0700136}
137
Aravind Akella724d91d2013-06-27 12:04:23 -0700138status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
Peng Xuda8385c2017-02-28 20:19:47 -0800139 int64_t maxBatchReportLatencyUs, int reservedFlags) const {
Aravind Akella724d91d2013-06-27 12:04:23 -0700140 return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
141 us2ns(maxBatchReportLatencyUs), reservedFlags);
142}
143
Aravind Akella701166d2013-10-08 14:59:26 -0700144status_t SensorEventQueue::flush() const {
145 return mSensorEventConnection->flush();
Mathias Agopiana7352c92010-07-14 23:41:37 -0700146}
147
148status_t SensorEventQueue::disableSensor(int32_t handle) const {
Aravind Akella724d91d2013-06-27 12:04:23 -0700149 return mSensorEventConnection->enableDisable(handle, false, 0, 0, false);
Mathias Agopiana7352c92010-07-14 23:41:37 -0700150}
151
152status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
Mathias Agopian589ce852010-07-13 22:21:56 -0700153 return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
154}
155
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700156status_t SensorEventQueue::injectSensorEvent(const ASensorEvent& event) {
Aravind Akella5c538052015-06-29 12:37:48 -0700157 do {
158 // Blocking call.
159 ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL);
160 if (size >= 0) {
161 return NO_ERROR;
162 } else if (size < 0 && errno == EAGAIN) {
163 // If send is returning a "Try again" error, sleep for 100ms and try again. In all
164 // other cases log a failure and exit.
165 usleep(100000);
166 } else {
167 ALOGE("injectSensorEvent failure %s %zd", strerror(errno), size);
168 return INVALID_OPERATION;
169 }
170 } while (true);
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700171}
172
Aravind Akella9a844cf2014-02-11 18:58:52 -0800173void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
174 for (int i = 0; i < count; ++i) {
175 if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
Aravind Akella8a969552014-09-28 17:52:41 -0700176 ++mNumAcksToSend;
177 }
178 }
179 // Send mNumAcksToSend to acknowledge for the wake up sensor events received.
180 if (mNumAcksToSend > 0) {
181 ssize_t size = ::send(mSensorChannel->getFd(), &mNumAcksToSend, sizeof(mNumAcksToSend),
182 MSG_DONTWAIT | MSG_NOSIGNAL);
183 if (size < 0) {
Dan Stozaf10c46e2014-11-11 10:32:31 -0800184 ALOGE("sendAck failure %zd %d", size, mNumAcksToSend);
Aravind Akella8a969552014-09-28 17:52:41 -0700185 } else {
186 mNumAcksToSend = 0;
Aravind Akella9a844cf2014-02-11 18:58:52 -0800187 }
188 }
189 return;
190}
191
Brian Stacke318d6b2019-01-16 15:43:37 -0800192ssize_t SensorEventQueue::filterEvents(ASensorEvent* events, size_t count) const {
193 // Check if this Sensor Event Queue is registered to receive each type of event. If it is not,
194 // then do not copy the event into the final buffer. Minimize the number of copy operations by
195 // finding consecutive sequences of events that the Sensor Event Queue should receive and only
196 // copying the events once an unregistered event type is reached.
197 bool intervalStartLocSet = false;
198 size_t intervalStartLoc = 0;
199 size_t eventsInInterval = 0;
200 ssize_t eventsCopied = 0;
201
202 for (size_t i = 0; i < count; i++) {
203 bool includeEvent =
204 (events[i].type != SENSOR_TYPE_ADDITIONAL_INFO || requestAdditionalInfo);
205
206 if (includeEvent) {
207 // Do not copy events yet since there may be more consecutive events that should be
208 // copied together. Track the start location and number of events in the current
209 // sequence.
210 if (!intervalStartLocSet) {
211 intervalStartLoc = i;
212 intervalStartLocSet = true;
213 eventsInInterval = 0;
214 }
215 eventsInInterval++;
216 }
217
218 // Shift the events from the already processed interval once an event that should not be
219 // included is reached or if this is the final event to be processed.
220 if (!includeEvent || (i + 1 == count)) {
221 // Only shift the events if the interval did not start with the first event. If the
222 // interval started with the first event, the events are already in their correct
223 // location.
224 if (intervalStartLoc > 0) {
225 memmove(&events[eventsCopied], &events[intervalStartLoc],
226 eventsInInterval * sizeof(ASensorEvent));
227 }
228 eventsCopied += eventsInInterval;
229
230 // Reset the interval information
231 eventsInInterval = 0;
232 intervalStartLocSet = false;
233 }
234 }
235 return eventsCopied;
236}
237
Mathias Agopian589ce852010-07-13 22:21:56 -0700238// ----------------------------------------------------------------------------
239}; // namespace android
240