diff options
| author | 2018-11-29 16:43:37 +0000 | |
|---|---|---|
| committer | 2018-11-29 16:43:37 +0000 | |
| commit | 4f16b43f0794f8972a37deb99fcd5a81df6b3060 (patch) | |
| tree | 2d40e79a8db33055ac0c9495a006f10c67805a35 | |
| parent | d2d06d7a076dabc2a860452f667bdd3bfadf37e4 (diff) | |
| parent | 93432adcde4bf5f95324373844ef299e2e3d6f6d (diff) | |
Merge "Prevent overflow when caching sensor events"
| -rw-r--r-- | services/sensorservice/SensorEventConnection.cpp | 76 | ||||
| -rw-r--r-- | services/sensorservice/SensorEventConnection.h | 4 |
2 files changed, 52 insertions, 28 deletions
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp index 0fb4ac6c11..8dc80cce18 100644 --- a/services/sensorservice/SensorEventConnection.cpp +++ b/services/sensorservice/SensorEventConnection.cpp @@ -315,32 +315,7 @@ status_t SensorService::SensorEventConnection::sendEvents( if (mCacheSize != 0) { // There are some events in the cache which need to be sent first. Copy this buffer to // the end of cache. - if (mCacheSize + count <= mMaxCacheSize) { - memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t)); - mCacheSize += count; - } else { - // Check if any new sensors have registered on this connection which may have increased - // the max cache size that is desired. - if (mCacheSize + count < computeMaxCacheSizeLocked()) { - reAllocateCacheLocked(scratch, count); - return status_t(NO_ERROR); - } - // Some events need to be dropped. - int remaningCacheSize = mMaxCacheSize - mCacheSize; - if (remaningCacheSize != 0) { - memcpy(&mEventCache[mCacheSize], scratch, - remaningCacheSize * sizeof(sensors_event_t)); - } - int numEventsDropped = count - remaningCacheSize; - countFlushCompleteEventsLocked(mEventCache, numEventsDropped); - // Drop the first "numEventsDropped" in the cache. - memmove(mEventCache, &mEventCache[numEventsDropped], - (mCacheSize - numEventsDropped) * sizeof(sensors_event_t)); - - // Copy the remainingEvents in scratch buffer to the end of cache. - memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize, - numEventsDropped * sizeof(sensors_event_t)); - } + appendEventsToCacheLocked(scratch, count); return status_t(NO_ERROR); } @@ -376,8 +351,8 @@ status_t SensorService::SensorEventConnection::sendEvents( mEventCache = new sensors_event_t[mMaxCacheSize]; mCacheSize = 0; } - memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t)); - mCacheSize += count; + // Save the events so that they can be written later + appendEventsToCacheLocked(scratch, count); // Add this file descriptor to the looper to get a callback when this fd is available for // writing. @@ -417,6 +392,51 @@ void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t mMaxCacheSize = new_cache_size; } +void SensorService::SensorEventConnection::appendEventsToCacheLocked(sensors_event_t const* events, + int count) { + if (count <= 0) { + return; + } else if (mCacheSize + count <= mMaxCacheSize) { + // The events fit within the current cache: add them + memcpy(&mEventCache[mCacheSize], events, count * sizeof(sensors_event_t)); + mCacheSize += count; + } else if (mCacheSize + count <= computeMaxCacheSizeLocked()) { + // The events fit within a resized cache: resize the cache and add the events + reAllocateCacheLocked(events, count); + } else { + // The events do not fit within the cache: drop the oldest events. + ALOGW("Dropping events from cache (%d / %d) to save %d newer events", mCacheSize, + mMaxCacheSize, count); + + int freeSpace = mMaxCacheSize - mCacheSize; + + // Drop up to the currently cached number of events to make room for new events + int cachedEventsToDrop = std::min(mCacheSize, count - freeSpace); + + // New events need to be dropped if there are more new events than the size of the cache + int newEventsToDrop = std::max(0, count - mMaxCacheSize); + + // Determine the number of new events to copy into the cache + int eventsToCopy = std::min(mMaxCacheSize, count); + + // Check for any flush complete events in the events that will be dropped + countFlushCompleteEventsLocked(mEventCache, cachedEventsToDrop); + countFlushCompleteEventsLocked(events, newEventsToDrop); + + // Only shift the events if they will not all be overwritten + if (eventsToCopy != mMaxCacheSize) { + memmove(mEventCache, &mEventCache[cachedEventsToDrop], + (mCacheSize - cachedEventsToDrop) * sizeof(sensors_event_t)); + } + mCacheSize -= cachedEventsToDrop; + + // Copy the events into the cache + memcpy(&mEventCache[mCacheSize], &events[newEventsToDrop], + eventsToCopy * sizeof(sensors_event_t)); + mCacheSize += eventsToCopy; + } +} + void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() { ASensorEvent flushCompleteEvent; memset(&flushCompleteEvent, 0, sizeof(flushCompleteEvent)); diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h index 40c21ff585..eefd81a258 100644 --- a/services/sensorservice/SensorEventConnection.h +++ b/services/sensorservice/SensorEventConnection.h @@ -108,6 +108,10 @@ private: // size, reallocate memory and copy over events from the older cache. void reAllocateCacheLocked(sensors_event_t const* scratch, int count); + // Add the events to the cache. If the cache would be exceeded, drop events at the beginning of + // the cache. + void appendEventsToCacheLocked(sensors_event_t const* events, int count); + // LooperCallback method. If there is data to read on this fd, it is an ack from the app that it // has read events from a wake up sensor, decrement mWakeLockRefCount. If this fd is available // for writing send the data from the cache. |