• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
16 
17 #define LOG_TAG "Sensors"
18 
19 #include <stdint.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 
23 #include <utils/Errors.h>
24 #include <utils/RefBase.h>
25 #include <utils/Looper.h>
26 
27 #include <gui/Sensor.h>
28 #include <gui/BitTube.h>
29 #include <gui/SensorEventQueue.h>
30 #include <gui/ISensorEventConnection.h>
31 
32 #include <android/sensor.h>
33 
34 // ----------------------------------------------------------------------------
35 namespace android {
36 // ----------------------------------------------------------------------------
37 
SensorEventQueue(const sp<ISensorEventConnection> & connection)38 SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
39     : mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0),
40       mNumAcksToSend(0) {
41     mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
42 }
43 
~SensorEventQueue()44 SensorEventQueue::~SensorEventQueue() {
45     delete [] mRecBuffer;
46 }
47 
onFirstRef()48 void SensorEventQueue::onFirstRef()
49 {
50     mSensorChannel = mSensorEventConnection->getSensorChannel();
51 }
52 
getFd() const53 int SensorEventQueue::getFd() const
54 {
55     return mSensorChannel->getFd();
56 }
57 
58 
write(const sp<BitTube> & tube,ASensorEvent const * events,size_t numEvents)59 ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
60         ASensorEvent const* events, size_t numEvents) {
61     return BitTube::sendObjects(tube, events, numEvents);
62 }
63 
read(ASensorEvent * events,size_t numEvents)64 ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
65     if (mAvailable == 0) {
66         ssize_t err = BitTube::recvObjects(mSensorChannel,
67                 mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
68         if (err < 0) {
69             return err;
70         }
71         mAvailable = err;
72         mConsumed = 0;
73     }
74     size_t count = numEvents < mAvailable ? numEvents : mAvailable;
75     memcpy(events, mRecBuffer + mConsumed, count*sizeof(ASensorEvent));
76     mAvailable -= count;
77     mConsumed += count;
78     return count;
79 }
80 
getLooper() const81 sp<Looper> SensorEventQueue::getLooper() const
82 {
83     Mutex::Autolock _l(mLock);
84     if (mLooper == 0) {
85         mLooper = new Looper(true);
86         mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, NULL, NULL);
87     }
88     return mLooper;
89 }
90 
waitForEvent() const91 status_t SensorEventQueue::waitForEvent() const
92 {
93     const int fd = getFd();
94     sp<Looper> looper(getLooper());
95 
96     int events;
97     int32_t result;
98     do {
99         result = looper->pollOnce(-1, NULL, &events, NULL);
100         if (result == ALOOPER_POLL_ERROR) {
101             ALOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
102             result = -EPIPE; // unknown error, so we make up one
103             break;
104         }
105         if (events & ALOOPER_EVENT_HANGUP) {
106             // the other-side has died
107             ALOGE("SensorEventQueue::waitForEvent error HANGUP");
108             result = -EPIPE; // unknown error, so we make up one
109             break;
110         }
111     } while (result != fd);
112 
113     return  (result == fd) ? status_t(NO_ERROR) : result;
114 }
115 
wake() const116 status_t SensorEventQueue::wake() const
117 {
118     sp<Looper> looper(getLooper());
119     looper->wake();
120     return NO_ERROR;
121 }
122 
enableSensor(Sensor const * sensor) const123 status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
124     return mSensorEventConnection->enableDisable(sensor->getHandle(), true, 0, 0, false);
125 }
126 
disableSensor(Sensor const * sensor) const127 status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
128     return mSensorEventConnection->enableDisable(sensor->getHandle(), false, 0, 0, false);
129 }
130 
enableSensor(int32_t handle,int32_t samplingPeriodUs,int maxBatchReportLatencyUs,int reservedFlags) const131 status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
132                                         int maxBatchReportLatencyUs, int reservedFlags) const {
133     return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
134                                                  us2ns(maxBatchReportLatencyUs), reservedFlags);
135 }
136 
flush() const137 status_t SensorEventQueue::flush() const {
138     return mSensorEventConnection->flush();
139 }
140 
disableSensor(int32_t handle) const141 status_t SensorEventQueue::disableSensor(int32_t handle) const {
142     return mSensorEventConnection->enableDisable(handle, false, 0, 0, false);
143 }
144 
setEventRate(Sensor const * sensor,nsecs_t ns) const145 status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
146     return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
147 }
148 
sendAck(const ASensorEvent * events,int count)149 void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
150     for (int i = 0; i < count; ++i) {
151         if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
152             ++mNumAcksToSend;
153         }
154     }
155     // Send mNumAcksToSend to acknowledge for the wake up sensor events received.
156     if (mNumAcksToSend > 0) {
157         ssize_t size = ::send(mSensorChannel->getFd(), &mNumAcksToSend, sizeof(mNumAcksToSend),
158                 MSG_DONTWAIT | MSG_NOSIGNAL);
159         if (size < 0) {
160             ALOGE("sendAck failure %d %d", size, mNumAcksToSend);
161         } else {
162             mNumAcksToSend = 0;
163         }
164     }
165     return;
166 }
167 
168 // ----------------------------------------------------------------------------
169 }; // namespace android
170 
171