SensorEventConnection.cpp revision 755c451c7861a029e26e5f16e319b629169e656d
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#include <sys/socket.h>
18#include <utils/threads.h>
19
20#include <gui/SensorEventQueue.h>
21
22#include "vec.h"
23#include "SensorEventConnection.h"
24#include "SensorDevice.h"
25
26namespace android {
27
28SensorService::SensorEventConnection::SensorEventConnection(
29        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
30        const String16& opPackageName)
31    : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
32      mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
33      mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
34    mChannel = new BitTube(mService->mSocketBufferSize);
35#if DEBUG_CONNECTIONS
36    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
37    mTotalAcksNeeded = mTotalAcksReceived = 0;
38#endif
39}
40
41SensorService::SensorEventConnection::~SensorEventConnection() {
42    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
43    mService->cleanupConnection(this);
44    if (mEventCache != NULL) {
45        delete mEventCache;
46    }
47}
48
49void SensorService::SensorEventConnection::onFirstRef() {
50    LooperCallback::onFirstRef();
51}
52
53bool SensorService::SensorEventConnection::needsWakeLock() {
54    Mutex::Autolock _l(mConnectionLock);
55    return !mDead && mWakeLockRefCount > 0;
56}
57
58void SensorService::SensorEventConnection::resetWakeLockRefCount() {
59    Mutex::Autolock _l(mConnectionLock);
60    mWakeLockRefCount = 0;
61}
62
63void SensorService::SensorEventConnection::dump(String8& result) {
64    Mutex::Autolock _l(mConnectionLock);
65    result.appendFormat("\tOperating Mode: %s\n",mDataInjectionMode ? "DATA_INJECTION" : "NORMAL");
66    result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
67            "max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
68            mMaxCacheSize);
69    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
70        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
71        result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
72                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
73                            mSensorInfo.keyAt(i),
74                            flushInfo.mFirstFlushPending ? "First flush pending" :
75                                                           "active",
76                            flushInfo.mPendingFlushEventsToSend);
77    }
78#if DEBUG_CONNECTIONS
79    result.appendFormat("\t events recvd: %d | sent %d | cache %d | dropped %d |"
80            " total_acks_needed %d | total_acks_recvd %d\n",
81            mEventsReceived,
82            mEventsSent,
83            mEventsSentFromCache,
84            mEventsReceived - (mEventsSentFromCache + mEventsSent + mCacheSize),
85            mTotalAcksNeeded,
86            mTotalAcksReceived);
87#endif
88}
89
90bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
91    Mutex::Autolock _l(mConnectionLock);
92    sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
93    if (si == nullptr ||
94        !canAccessSensor(si->getSensor(), "Tried adding", mOpPackageName) ||
95        mSensorInfo.indexOfKey(handle) >= 0) {
96        return false;
97    }
98    mSensorInfo.add(handle, FlushInfo());
99    return true;
100}
101
102bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
103    Mutex::Autolock _l(mConnectionLock);
104    if (mSensorInfo.removeItem(handle) >= 0) {
105        return true;
106    }
107    return false;
108}
109
110bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
111    Mutex::Autolock _l(mConnectionLock);
112    return mSensorInfo.indexOfKey(handle) >= 0;
113}
114
115bool SensorService::SensorEventConnection::hasAnySensor() const {
116    Mutex::Autolock _l(mConnectionLock);
117    return mSensorInfo.size() ? true : false;
118}
119
120bool SensorService::SensorEventConnection::hasOneShotSensors() const {
121    Mutex::Autolock _l(mConnectionLock);
122    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
123        const int handle = mSensorInfo.keyAt(i);
124        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
125        if (si != nullptr && si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
126            return true;
127        }
128    }
129    return false;
130}
131
132String8 SensorService::SensorEventConnection::getPackageName() const {
133    return mPackageName;
134}
135
136void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
137                                bool value) {
138    Mutex::Autolock _l(mConnectionLock);
139    ssize_t index = mSensorInfo.indexOfKey(handle);
140    if (index >= 0) {
141        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
142        flushInfo.mFirstFlushPending = value;
143    }
144}
145
146void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
147    Mutex::Autolock _l(mConnectionLock);
148    updateLooperRegistrationLocked(looper);
149}
150
151void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
152        const sp<Looper>& looper) {
153    bool isConnectionActive = (mSensorInfo.size() > 0 && !mDataInjectionMode) ||
154                              mDataInjectionMode;
155    // If all sensors are unregistered OR Looper has encountered an error, we can remove the Fd from
156    // the Looper if it has been previously added.
157    if (!isConnectionActive || mDead) { if (mHasLooperCallbacks) {
158        ALOGD_IF(DEBUG_CONNECTIONS, "%p removeFd fd=%d", this,
159                 mChannel->getSendFd());
160        looper->removeFd(mChannel->getSendFd()); mHasLooperCallbacks = false; }
161    return; }
162
163    int looper_flags = 0;
164    if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
165    if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
166    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
167        const int handle = mSensorInfo.keyAt(i);
168        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
169        if (si != nullptr && si->getSensor().isWakeUpSensor()) {
170            looper_flags |= ALOOPER_EVENT_INPUT;
171        }
172    }
173
174    // If flags is still set to zero, we don't need to add this fd to the Looper, if the fd has
175    // already been added, remove it. This is likely to happen when ALL the events stored in the
176    // cache have been sent to the corresponding app.
177    if (looper_flags == 0) {
178        if (mHasLooperCallbacks) {
179            ALOGD_IF(DEBUG_CONNECTIONS, "removeFd fd=%d", mChannel->getSendFd());
180            looper->removeFd(mChannel->getSendFd());
181            mHasLooperCallbacks = false;
182        }
183        return;
184    }
185
186    // Add the file descriptor to the Looper for receiving acknowledegments if the app has
187    // registered for wake-up sensors OR for sending events in the cache.
188    int ret = looper->addFd(mChannel->getSendFd(), 0, looper_flags, this, NULL);
189    if (ret == 1) {
190        ALOGD_IF(DEBUG_CONNECTIONS, "%p addFd fd=%d", this, mChannel->getSendFd());
191        mHasLooperCallbacks = true;
192    } else {
193        ALOGE("Looper::addFd failed ret=%d fd=%d", ret, mChannel->getSendFd());
194    }
195}
196
197void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
198    Mutex::Autolock _l(mConnectionLock);
199    ssize_t index = mSensorInfo.indexOfKey(handle);
200    if (index >= 0) {
201        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
202        flushInfo.mPendingFlushEventsToSend++;
203    }
204}
205
206status_t SensorService::SensorEventConnection::sendEvents(
207        sensors_event_t const* buffer, size_t numEvents,
208        sensors_event_t* scratch,
209        SensorEventConnection const * const * mapFlushEventsToConnections) {
210    // filter out events not for this connection
211    int count = 0;
212    Mutex::Autolock _l(mConnectionLock);
213    if (scratch) {
214        size_t i=0;
215        while (i<numEvents) {
216            int32_t sensor_handle = buffer[i].sensor;
217            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
218                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
219                        buffer[i].meta_data.sensor);
220                // Setting sensor_handle to the correct sensor to ensure the sensor events per
221                // connection are filtered correctly.  buffer[i].sensor is zero for meta_data
222                // events.
223                sensor_handle = buffer[i].meta_data.sensor;
224            }
225
226            ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
227            // Check if this connection has registered for this sensor. If not continue to the
228            // next sensor_event.
229            if (index < 0) {
230                ++i;
231                continue;
232            }
233
234            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
235            // Check if there is a pending flush_complete event for this sensor on this connection.
236            if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
237                    this == mapFlushEventsToConnections[i]) {
238                flushInfo.mFirstFlushPending = false;
239                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
240                        buffer[i].meta_data.sensor);
241                ++i;
242                continue;
243            }
244
245            // If there is a pending flush complete event for this sensor on this connection,
246            // ignore the event and proceed to the next.
247            if (flushInfo.mFirstFlushPending) {
248                ++i;
249                continue;
250            }
251
252            do {
253                // Keep copying events into the scratch buffer as long as they are regular
254                // sensor_events are from the same sensor_handle OR they are flush_complete_events
255                // from the same sensor_handle AND the current connection is mapped to the
256                // corresponding flush_complete_event.
257                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
258                    if (this == mapFlushEventsToConnections[i]) {
259                        scratch[count++] = buffer[i];
260                    }
261                    ++i;
262                } else {
263                    // Regular sensor event, just copy it to the scratch buffer.
264                    scratch[count++] = buffer[i++];
265                }
266            } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
267                                        buffer[i].type != SENSOR_TYPE_META_DATA) ||
268                                       (buffer[i].type == SENSOR_TYPE_META_DATA  &&
269                                        buffer[i].meta_data.sensor == sensor_handle)));
270        }
271    } else {
272        scratch = const_cast<sensors_event_t *>(buffer);
273        count = numEvents;
274    }
275
276    sendPendingFlushEventsLocked();
277    // Early return if there are no events for this connection.
278    if (count == 0) {
279        return status_t(NO_ERROR);
280    }
281
282#if DEBUG_CONNECTIONS
283     mEventsReceived += count;
284#endif
285    if (mCacheSize != 0) {
286        // There are some events in the cache which need to be sent first. Copy this buffer to
287        // the end of cache.
288        if (mCacheSize + count <= mMaxCacheSize) {
289            memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
290            mCacheSize += count;
291        } else {
292            // Check if any new sensors have registered on this connection which may have increased
293            // the max cache size that is desired.
294            if (mCacheSize + count < computeMaxCacheSizeLocked()) {
295                reAllocateCacheLocked(scratch, count);
296                return status_t(NO_ERROR);
297            }
298            // Some events need to be dropped.
299            int remaningCacheSize = mMaxCacheSize - mCacheSize;
300            if (remaningCacheSize != 0) {
301                memcpy(&mEventCache[mCacheSize], scratch,
302                                                remaningCacheSize * sizeof(sensors_event_t));
303            }
304            int numEventsDropped = count - remaningCacheSize;
305            countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
306            // Drop the first "numEventsDropped" in the cache.
307            memmove(mEventCache, &mEventCache[numEventsDropped],
308                    (mCacheSize - numEventsDropped) * sizeof(sensors_event_t));
309
310            // Copy the remainingEvents in scratch buffer to the end of cache.
311            memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
312                                            numEventsDropped * sizeof(sensors_event_t));
313        }
314        return status_t(NO_ERROR);
315    }
316
317    int index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
318    if (index_wake_up_event >= 0) {
319        scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
320        ++mWakeLockRefCount;
321#if DEBUG_CONNECTIONS
322        ++mTotalAcksNeeded;
323#endif
324    }
325
326    // NOTE: ASensorEvent and sensors_event_t are the same type.
327    ssize_t size = SensorEventQueue::write(mChannel,
328                                    reinterpret_cast<ASensorEvent const*>(scratch), count);
329    if (size < 0) {
330        // Write error, copy events to local cache.
331        if (index_wake_up_event >= 0) {
332            // If there was a wake_up sensor_event, reset the flag.
333            scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
334            if (mWakeLockRefCount > 0) {
335                --mWakeLockRefCount;
336            }
337#if DEBUG_CONNECTIONS
338            --mTotalAcksNeeded;
339#endif
340        }
341        if (mEventCache == NULL) {
342            mMaxCacheSize = computeMaxCacheSizeLocked();
343            mEventCache = new sensors_event_t[mMaxCacheSize];
344            mCacheSize = 0;
345        }
346        memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
347        mCacheSize += count;
348
349        // Add this file descriptor to the looper to get a callback when this fd is available for
350        // writing.
351        updateLooperRegistrationLocked(mService->getLooper());
352        return size;
353    }
354
355#if DEBUG_CONNECTIONS
356    if (size > 0) {
357        mEventsSent += count;
358    }
359#endif
360
361    return size < 0 ? status_t(size) : status_t(NO_ERROR);
362}
363
364void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
365                                                                 int count) {
366    sensors_event_t *eventCache_new;
367    const int new_cache_size = computeMaxCacheSizeLocked();
368    // Allocate new cache, copy over events from the old cache & scratch, free up memory.
369    eventCache_new = new sensors_event_t[new_cache_size];
370    memcpy(eventCache_new, mEventCache, mCacheSize * sizeof(sensors_event_t));
371    memcpy(&eventCache_new[mCacheSize], scratch, count * sizeof(sensors_event_t));
372
373    ALOGD_IF(DEBUG_CONNECTIONS, "reAllocateCacheLocked maxCacheSize=%d %d", mMaxCacheSize,
374            new_cache_size);
375
376    delete mEventCache;
377    mEventCache = eventCache_new;
378    mCacheSize += count;
379    mMaxCacheSize = new_cache_size;
380}
381
382void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
383    ASensorEvent flushCompleteEvent;
384    memset(&flushCompleteEvent, 0, sizeof(flushCompleteEvent));
385    flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
386    // Loop through all the sensors for this connection and check if there are any pending
387    // flush complete events to be sent.
388    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
389        const int handle = mSensorInfo.keyAt(i);
390        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
391        if (si == nullptr) {
392            continue;
393        }
394
395        FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
396        while (flushInfo.mPendingFlushEventsToSend > 0) {
397            flushCompleteEvent.meta_data.sensor = handle;
398            bool wakeUpSensor = si->getSensor().isWakeUpSensor();
399            if (wakeUpSensor) {
400               ++mWakeLockRefCount;
401               flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
402            }
403            ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
404            if (size < 0) {
405                if (wakeUpSensor) --mWakeLockRefCount;
406                return;
407            }
408            ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
409                    flushCompleteEvent.meta_data.sensor);
410            flushInfo.mPendingFlushEventsToSend--;
411        }
412    }
413}
414
415void SensorService::SensorEventConnection::writeToSocketFromCache() {
416    // At a time write at most half the size of the receiver buffer in SensorEventQueue OR
417    // half the size of the socket buffer allocated in BitTube whichever is smaller.
418    const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
419            int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
420    Mutex::Autolock _l(mConnectionLock);
421    // Send pending flush complete events (if any)
422    sendPendingFlushEventsLocked();
423    for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
424        const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
425        int index_wake_up_event =
426                  findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
427        if (index_wake_up_event >= 0) {
428            mEventCache[index_wake_up_event + numEventsSent].flags |=
429                    WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
430            ++mWakeLockRefCount;
431#if DEBUG_CONNECTIONS
432            ++mTotalAcksNeeded;
433#endif
434        }
435
436        ssize_t size = SensorEventQueue::write(mChannel,
437                          reinterpret_cast<ASensorEvent const*>(mEventCache + numEventsSent),
438                          numEventsToWrite);
439        if (size < 0) {
440            if (index_wake_up_event >= 0) {
441                // If there was a wake_up sensor_event, reset the flag.
442                mEventCache[index_wake_up_event + numEventsSent].flags  &=
443                        ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
444                if (mWakeLockRefCount > 0) {
445                    --mWakeLockRefCount;
446                }
447#if DEBUG_CONNECTIONS
448                --mTotalAcksNeeded;
449#endif
450            }
451            memmove(mEventCache, &mEventCache[numEventsSent],
452                                 (mCacheSize - numEventsSent) * sizeof(sensors_event_t));
453            ALOGD_IF(DEBUG_CONNECTIONS, "wrote %d events from cache size==%d ",
454                    numEventsSent, mCacheSize);
455            mCacheSize -= numEventsSent;
456            return;
457        }
458        numEventsSent += numEventsToWrite;
459#if DEBUG_CONNECTIONS
460        mEventsSentFromCache += numEventsToWrite;
461#endif
462    }
463    ALOGD_IF(DEBUG_CONNECTIONS, "wrote all events from cache size=%d ", mCacheSize);
464    // All events from the cache have been sent. Reset cache size to zero.
465    mCacheSize = 0;
466    // There are no more events in the cache. We don't need to poll for write on the fd.
467    // Update Looper registration.
468    updateLooperRegistrationLocked(mService->getLooper());
469}
470
471void SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
472                sensors_event_t const* scratch, const int numEventsDropped) {
473    ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
474    // Count flushComplete events in the events that are about to the dropped. These will be sent
475    // separately before the next batch of events.
476    for (int j = 0; j < numEventsDropped; ++j) {
477        if (scratch[j].type == SENSOR_TYPE_META_DATA) {
478            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
479            flushInfo.mPendingFlushEventsToSend++;
480            ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
481                     flushInfo.mPendingFlushEventsToSend);
482        }
483    }
484    return;
485}
486
487int SensorService::SensorEventConnection::findWakeUpSensorEventLocked(
488                       sensors_event_t const* scratch, const int count) {
489    for (int i = 0; i < count; ++i) {
490        if (mService->isWakeUpSensorEvent(scratch[i])) {
491            return i;
492        }
493    }
494    return -1;
495}
496
497sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
498{
499    return mChannel;
500}
501
502status_t SensorService::SensorEventConnection::enableDisable(
503        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
504        int reservedFlags)
505{
506    status_t err;
507    if (enabled) {
508        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
509                               reservedFlags, mOpPackageName);
510
511    } else {
512        err = mService->disable(this, handle);
513    }
514    return err;
515}
516
517status_t SensorService::SensorEventConnection::setEventRate(
518        int handle, nsecs_t samplingPeriodNs)
519{
520    return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
521}
522
523status_t  SensorService::SensorEventConnection::flush() {
524    return  mService->flushSensor(this, mOpPackageName);
525}
526
527int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) {
528    if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) {
529        {
530            // If the Looper encounters some error, set the flag mDead, reset mWakeLockRefCount,
531            // and remove the fd from Looper. Call checkWakeLockState to know if SensorService
532            // can release the wake-lock.
533            ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
534            Mutex::Autolock _l(mConnectionLock);
535            mDead = true;
536            mWakeLockRefCount = 0;
537            updateLooperRegistrationLocked(mService->getLooper());
538        }
539        mService->checkWakeLockState();
540        if (mDataInjectionMode) {
541            // If the Looper has encountered some error in data injection mode, reset SensorService
542            // back to normal mode.
543            mService->resetToNormalMode();
544            mDataInjectionMode = false;
545        }
546        return 1;
547    }
548
549    if (events & ALOOPER_EVENT_INPUT) {
550        unsigned char buf[sizeof(sensors_event_t)];
551        ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
552        {
553            Mutex::Autolock _l(mConnectionLock);
554            if (numBytesRead == sizeof(sensors_event_t)) {
555                if (!mDataInjectionMode) {
556                    ALOGE("Data injected in normal mode, dropping event"
557                          "package=%s uid=%d", mPackageName.string(), mUid);
558                    // Unregister call backs.
559                    return 0;
560                }
561                sensors_event_t sensor_event;
562                memcpy(&sensor_event, buf, sizeof(sensors_event_t));
563                sp<SensorInterface> si =
564                        mService->getSensorInterfaceFromHandle(sensor_event.sensor);
565                if (si == nullptr) {
566                    return 1;
567                }
568
569                SensorDevice& dev(SensorDevice::getInstance());
570                sensor_event.type = si->getSensor().getType();
571                dev.injectSensorData(&sensor_event);
572#if DEBUG_CONNECTIONS
573                ++mEventsReceived;
574#endif
575            } else if (numBytesRead == sizeof(uint32_t)) {
576                uint32_t numAcks = 0;
577                memcpy(&numAcks, buf, numBytesRead);
578                // Sanity check to ensure  there are no read errors in recv, numAcks is always
579                // within the range and not zero. If any of the above don't hold reset
580                // mWakeLockRefCount to zero.
581                if (numAcks > 0 && numAcks < mWakeLockRefCount) {
582                    mWakeLockRefCount -= numAcks;
583                } else {
584                    mWakeLockRefCount = 0;
585                }
586#if DEBUG_CONNECTIONS
587                mTotalAcksReceived += numAcks;
588#endif
589           } else {
590               // Read error, reset wakelock refcount.
591               mWakeLockRefCount = 0;
592           }
593        }
594        // Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
595        // here as checkWakeLockState() will need it.
596        if (mWakeLockRefCount == 0) {
597            mService->checkWakeLockState();
598        }
599        // continue getting callbacks.
600        return 1;
601    }
602
603    if (events & ALOOPER_EVENT_OUTPUT) {
604        // send sensor data that is stored in mEventCache for this connection.
605        mService->sendEventsFromCache(this);
606    }
607    return 1;
608}
609
610int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
611    size_t fifoWakeUpSensors = 0;
612    size_t fifoNonWakeUpSensors = 0;
613    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
614        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(mSensorInfo.keyAt(i));
615        if (si == nullptr) {
616            continue;
617        }
618        const Sensor& sensor = si->getSensor();
619        if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) {
620            // Each sensor has a reserved fifo. Sum up the fifo sizes for all wake up sensors and
621            // non wake_up sensors.
622            if (sensor.isWakeUpSensor()) {
623                fifoWakeUpSensors += sensor.getFifoReservedEventCount();
624            } else {
625                fifoNonWakeUpSensors += sensor.getFifoReservedEventCount();
626            }
627        } else {
628            // Shared fifo. Compute the max of the fifo sizes for wake_up and non_wake up sensors.
629            if (sensor.isWakeUpSensor()) {
630                fifoWakeUpSensors = fifoWakeUpSensors > sensor.getFifoMaxEventCount() ?
631                                          fifoWakeUpSensors : sensor.getFifoMaxEventCount();
632
633            } else {
634                fifoNonWakeUpSensors = fifoNonWakeUpSensors > sensor.getFifoMaxEventCount() ?
635                                          fifoNonWakeUpSensors : sensor.getFifoMaxEventCount();
636
637            }
638        }
639   }
640   if (fifoWakeUpSensors + fifoNonWakeUpSensors == 0) {
641       // It is extremely unlikely that there is a write failure in non batch mode. Return a cache
642       // size that is equal to that of the batch mode.
643       // ALOGW("Write failure in non-batch mode");
644       return MAX_SOCKET_BUFFER_SIZE_BATCHED/sizeof(sensors_event_t);
645   }
646   return fifoWakeUpSensors + fifoNonWakeUpSensors;
647}
648
649} // namespace android
650
651