Divide huge SensorService files into managable pieces
Splitted SensorService.cpp and SensorService.h into smaller more
manageable pieces with the embedded classes/structs now in individual
files.
Change-Id: I5e75c41b9e0e5c9aff102fe4b0f142c61d1203e2
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index b6a5d66..acad61c 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -14,30 +14,13 @@
* limitations under the License.
*/
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
#include <cutils/properties.h>
-#include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Singleton.h>
-#include <utils/String16.h>
-
#include <binder/AppOpsManager.h>
#include <binder/BinderService.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
#include <gui/SensorEventQueue.h>
#include <hardware/sensors.h>
@@ -50,7 +33,19 @@
#include "OrientationSensor.h"
#include "RotationVectorSensor.h"
#include "SensorFusion.h"
+
#include "SensorService.h"
+#include "SensorEventConnection.h"
+#include "SensorEventAckReceiver.h"
+#include "SensorRecord.h"
+#include "SensorRegistrationInfo.h"
+#include "MostRecentEventLogger.h"
+
+#include <inttypes.h>
+#include <math.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/socket.h>
namespace android {
// ---------------------------------------------------------------------------
@@ -282,8 +277,7 @@
{
String8 result;
if (!PermissionCache::checkCallingPermission(sDump)) {
- result.appendFormat("Permission Denial: "
- "can't dump SensorService from pid=%d, uid=%d\n",
+ result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n",
IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid());
} else {
@@ -396,7 +390,7 @@
int bufIndex = mLastEventSeen.indexOfKey(s.getHandle());
if (bufIndex >= 0) {
- const CircularBuffer* buf = mLastEventSeen.valueAt(bufIndex);
+ const MostRecentEventLogger* buf = mLastEventSeen.valueAt(bufIndex);
if (buf != NULL && s.getRequiredPermission().isEmpty()) {
buf->printBuffer(result);
} else {
@@ -500,9 +494,9 @@
{
ALOGD("nuSensorService thread starting...");
- // each virtual sensor could generate an event per "real" event, that's why we need
- // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
- // in practice, this is too aggressive, but guaranteed to be enough.
+ // each virtual sensor could generate an event per "real" event, that's why we need to size
+ // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too
+ // aggressive, but guaranteed to be enough.
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
@@ -522,14 +516,15 @@
mSensorEventBuffer[i].flags = 0;
}
- // Make a copy of the connection vector as some connections may be removed during the
- // course of this loop (especially when one-shot sensor events are present in the
- // sensor_event buffer). Promote all connections to StrongPointers before the lock is
- // acquired. If the destructor of the sp gets called when the lock is acquired, it may
- // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for
- // cleanup. So copy all the strongPointers to a vector before the lock is acquired.
+ // Make a copy of the connection vector as some connections may be removed during the course
+ // of this loop (especially when one-shot sensor events are present in the sensor_event
+ // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
+ // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
+ // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
+ // strongPointers to a vector before the lock is acquired.
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
+
Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
// rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
@@ -598,10 +593,10 @@
}
}
- // Map flush_complete_events in the buffer to SensorEventConnections which called
- // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the
- // SensorEventConnection mapped to the corresponding flush_complete_event in
- // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
+ // Map flush_complete_events in the buffer to SensorEventConnections which called flush on
+ // the hardware sensor. mapFlushEventsToConnections[i] will be the SensorEventConnection
+ // mapped to the corresponding flush_complete_event in mSensorEventBuffer[i] if such a
+ // mapping exists (NULL otherwise).
for (int i = 0; i < count; ++i) {
mMapFlushEventsToConnections[i] = NULL;
if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
@@ -699,9 +694,9 @@
const sensors_event_t* buffer, size_t count) {
for (size_t i = 0; i < count; i++) {
if (buffer[i].type != SENSOR_TYPE_META_DATA) {
- CircularBuffer* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
+ MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
if (circular_buf == NULL) {
- circular_buf = new CircularBuffer(buffer[i].type);
+ circular_buf = new MostRecentEventLogger(buffer[i].type);
}
circular_buf->addEvent(buffer[i]);
}
@@ -900,7 +895,7 @@
if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
// NOTE: The wake_up flag of this event may get set to
// WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
- CircularBuffer *circular_buf = mLastEventSeen.valueFor(handle);
+ MostRecentEventLogger *circular_buf = mLastEventSeen.valueFor(handle);
if (circular_buf) {
sensors_event_t event;
memset(&event, 0, sizeof(event));
@@ -1224,779 +1219,5 @@
}
}
-// ---------------------------------------------------------------------------
-SensorService::SensorRecord::SensorRecord(
- const sp<SensorEventConnection>& connection)
-{
- mConnections.add(connection);
-}
-
-bool SensorService::SensorRecord::addConnection(
- const sp<SensorEventConnection>& connection)
-{
- if (mConnections.indexOf(connection) < 0) {
- mConnections.add(connection);
- return true;
- }
- return false;
-}
-
-bool SensorService::SensorRecord::removeConnection(
- const wp<SensorEventConnection>& connection)
-{
- ssize_t index = mConnections.indexOf(connection);
- if (index >= 0) {
- mConnections.removeItemsAt(index, 1);
- }
- // Remove this connections from the queue of flush() calls made on this sensor.
- for (Vector< wp<SensorEventConnection> >::iterator it =
- mPendingFlushConnections.begin(); it != mPendingFlushConnections.end();) {
-
- if (it->unsafe_get() == connection.unsafe_get()) {
- it = mPendingFlushConnections.erase(it);
- } else {
- ++it;
- }
- }
- return mConnections.size() ? false : true;
-}
-
-void SensorService::SensorRecord::addPendingFlushConnection(
- const sp<SensorEventConnection>& connection) {
- mPendingFlushConnections.add(connection);
-}
-
-void SensorService::SensorRecord::removeFirstPendingFlushConnection() {
- if (mPendingFlushConnections.size() > 0) {
- mPendingFlushConnections.removeAt(0);
- }
-}
-
-SensorService::SensorEventConnection *
-SensorService::SensorRecord::getFirstPendingFlushConnection() {
- if (mPendingFlushConnections.size() > 0) {
- return mPendingFlushConnections[0].unsafe_get();
- }
- return NULL;
-}
-
-void SensorService::SensorRecord::clearAllPendingFlushConnections() {
- mPendingFlushConnections.clear();
-}
-
-
-// ---------------------------------------------------------------------------
-SensorService::TrimmedSensorEvent::TrimmedSensorEvent(int sensorType) {
- mTimestamp = -1;
- const int numData = SensorService::getNumEventsForSensorType(sensorType);
- if (sensorType == SENSOR_TYPE_STEP_COUNTER) {
- mStepCounter = 0;
- } else {
- mData = new float[numData];
- for (int i = 0; i < numData; ++i) {
- mData[i] = -1.0;
- }
- }
- mHour = mMin = mSec = INT32_MIN;
-}
-
-bool SensorService::TrimmedSensorEvent::isSentinel(const TrimmedSensorEvent& event) {
- return (event.mHour == INT32_MIN && event.mMin == INT32_MIN && event.mSec == INT32_MIN);
-}
-// --------------------------------------------------------------------------
-SensorService::CircularBuffer::CircularBuffer(int sensor_event_type) {
- mNextInd = 0;
- mBufSize = CIRCULAR_BUF_SIZE;
- if (sensor_event_type == SENSOR_TYPE_STEP_COUNTER ||
- sensor_event_type == SENSOR_TYPE_SIGNIFICANT_MOTION ||
- sensor_event_type == SENSOR_TYPE_ACCELEROMETER) {
- mBufSize = CIRCULAR_BUF_SIZE * 5;
- }
- mTrimmedSensorEventArr = new TrimmedSensorEvent *[mBufSize];
- mSensorType = sensor_event_type;
- for (int i = 0; i < mBufSize; ++i) {
- mTrimmedSensorEventArr[i] = new TrimmedSensorEvent(mSensorType);
- }
-}
-
-void SensorService::CircularBuffer::addEvent(const sensors_event_t& sensor_event) {
- TrimmedSensorEvent *curr_event = mTrimmedSensorEventArr[mNextInd];
- curr_event->mTimestamp = sensor_event.timestamp;
- if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
- curr_event->mStepCounter = sensor_event.u64.step_counter;
- } else {
- memcpy(curr_event->mData, sensor_event.data,
- sizeof(float) * SensorService::getNumEventsForSensorType(mSensorType));
- }
- time_t rawtime = time(NULL);
- struct tm * timeinfo = localtime(&rawtime);
- curr_event->mHour = timeinfo->tm_hour;
- curr_event->mMin = timeinfo->tm_min;
- curr_event->mSec = timeinfo->tm_sec;
- mNextInd = (mNextInd + 1) % mBufSize;
-}
-
-void SensorService::CircularBuffer::printBuffer(String8& result) const {
- const int numData = SensorService::getNumEventsForSensorType(mSensorType);
- int i = mNextInd, eventNum = 1;
- result.appendFormat("last %d events = < ", mBufSize);
- do {
- if (TrimmedSensorEvent::isSentinel(*mTrimmedSensorEventArr[i])) {
- // Sentinel, ignore.
- i = (i + 1) % mBufSize;
- continue;
- }
- result.appendFormat("%d) ", eventNum++);
- if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
- result.appendFormat("%" PRIu64 ",", mTrimmedSensorEventArr[i]->mStepCounter);
- } else {
- for (int j = 0; j < numData; ++j) {
- result.appendFormat("%5.1f,", mTrimmedSensorEventArr[i]->mData[j]);
- }
- }
- result.appendFormat("%" PRId64 " %02d:%02d:%02d ", mTrimmedSensorEventArr[i]->mTimestamp,
- mTrimmedSensorEventArr[i]->mHour, mTrimmedSensorEventArr[i]->mMin,
- mTrimmedSensorEventArr[i]->mSec);
- i = (i + 1) % mBufSize;
- } while (i != mNextInd);
- result.appendFormat(">\n");
-}
-
-bool SensorService::CircularBuffer::populateLastEvent(sensors_event_t *event) {
- int lastEventInd = (mNextInd - 1 + mBufSize) % mBufSize;
- // Check if the buffer is empty.
- if (TrimmedSensorEvent::isSentinel(*mTrimmedSensorEventArr[lastEventInd])) {
- return false;
- }
- event->version = sizeof(sensors_event_t);
- event->type = mSensorType;
- event->timestamp = mTrimmedSensorEventArr[lastEventInd]->mTimestamp;
- if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
- event->u64.step_counter = mTrimmedSensorEventArr[lastEventInd]->mStepCounter;
- } else {
- memcpy(event->data, mTrimmedSensorEventArr[lastEventInd]->mData,
- sizeof(float) * SensorService::getNumEventsForSensorType(mSensorType));
- }
- return true;
-}
-
-SensorService::CircularBuffer::~CircularBuffer() {
- for (int i = 0; i < mBufSize; ++i) {
- delete mTrimmedSensorEventArr[i];
- }
- delete [] mTrimmedSensorEventArr;
-}
-
-// ---------------------------------------------------------------------------
-
-SensorService::SensorEventConnection::SensorEventConnection(
- const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
- const String16& opPackageName)
- : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
- mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
- mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
- mChannel = new BitTube(mService->mSocketBufferSize);
-#if DEBUG_CONNECTIONS
- mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
- mTotalAcksNeeded = mTotalAcksReceived = 0;
-#endif
-}
-
-SensorService::SensorEventConnection::~SensorEventConnection() {
- ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
- mService->cleanupConnection(this);
- if (mEventCache != NULL) {
- delete mEventCache;
- }
-}
-
-void SensorService::SensorEventConnection::onFirstRef() {
- LooperCallback::onFirstRef();
-}
-
-bool SensorService::SensorEventConnection::needsWakeLock() {
- Mutex::Autolock _l(mConnectionLock);
- return !mDead && mWakeLockRefCount > 0;
-}
-
-void SensorService::SensorEventConnection::resetWakeLockRefCount() {
- Mutex::Autolock _l(mConnectionLock);
- mWakeLockRefCount = 0;
-}
-
-void SensorService::SensorEventConnection::dump(String8& result) {
- Mutex::Autolock _l(mConnectionLock);
- result.appendFormat("\tOperating Mode: %s\n",mDataInjectionMode ? "DATA_INJECTION" : "NORMAL");
- result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
- "max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
- mMaxCacheSize);
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
- result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
- mService->getSensorName(mSensorInfo.keyAt(i)).string(),
- mSensorInfo.keyAt(i),
- flushInfo.mFirstFlushPending ? "First flush pending" :
- "active",
- flushInfo.mPendingFlushEventsToSend);
- }
-#if DEBUG_CONNECTIONS
- result.appendFormat("\t events recvd: %d | sent %d | cache %d | dropped %d |"
- " total_acks_needed %d | total_acks_recvd %d\n",
- mEventsReceived,
- mEventsSent,
- mEventsSentFromCache,
- mEventsReceived - (mEventsSentFromCache + mEventsSent + mCacheSize),
- mTotalAcksNeeded,
- mTotalAcksReceived);
-#endif
-}
-
-bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
- Mutex::Autolock _l(mConnectionLock);
- if (!canAccessSensor(mService->getSensorFromHandle(handle),
- "Tried adding", mOpPackageName)) {
- return false;
- }
- if (mSensorInfo.indexOfKey(handle) < 0) {
- mSensorInfo.add(handle, FlushInfo());
- return true;
- }
- return false;
-}
-
-bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
- Mutex::Autolock _l(mConnectionLock);
- if (mSensorInfo.removeItem(handle) >= 0) {
- return true;
- }
- return false;
-}
-
-bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
- Mutex::Autolock _l(mConnectionLock);
- return mSensorInfo.indexOfKey(handle) >= 0;
-}
-
-bool SensorService::SensorEventConnection::hasAnySensor() const {
- Mutex::Autolock _l(mConnectionLock);
- return mSensorInfo.size() ? true : false;
-}
-
-bool SensorService::SensorEventConnection::hasOneShotSensors() const {
- Mutex::Autolock _l(mConnectionLock);
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const int handle = mSensorInfo.keyAt(i);
- if (mService->getSensorFromHandle(handle).getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
- return true;
- }
- }
- return false;
-}
-
-String8 SensorService::SensorEventConnection::getPackageName() const {
- return mPackageName;
-}
-
-void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
- bool value) {
- Mutex::Autolock _l(mConnectionLock);
- ssize_t index = mSensorInfo.indexOfKey(handle);
- if (index >= 0) {
- FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
- flushInfo.mFirstFlushPending = value;
- }
-}
-
-void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
- Mutex::Autolock _l(mConnectionLock);
- updateLooperRegistrationLocked(looper);
-}
-
-void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
- const sp<Looper>& looper) {
- bool isConnectionActive = (mSensorInfo.size() > 0 && !mDataInjectionMode) ||
- mDataInjectionMode;
- // If all sensors are unregistered OR Looper has encountered an error, we
- // can remove the Fd from the Looper if it has been previously added.
- if (!isConnectionActive || mDead) {
- if (mHasLooperCallbacks) {
- ALOGD_IF(DEBUG_CONNECTIONS, "%p removeFd fd=%d", this, mChannel->getSendFd());
- looper->removeFd(mChannel->getSendFd());
- mHasLooperCallbacks = false;
- }
- return;
- }
-
- int looper_flags = 0;
- if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
- if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const int handle = mSensorInfo.keyAt(i);
- if (mService->getSensorFromHandle(handle).isWakeUpSensor()) {
- looper_flags |= ALOOPER_EVENT_INPUT;
- break;
- }
- }
- // If flags is still set to zero, we don't need to add this fd to the Looper, if
- // the fd has already been added, remove it. This is likely to happen when ALL the
- // events stored in the cache have been sent to the corresponding app.
- if (looper_flags == 0) {
- if (mHasLooperCallbacks) {
- ALOGD_IF(DEBUG_CONNECTIONS, "removeFd fd=%d", mChannel->getSendFd());
- looper->removeFd(mChannel->getSendFd());
- mHasLooperCallbacks = false;
- }
- return;
- }
- // Add the file descriptor to the Looper for receiving acknowledegments if the app has
- // registered for wake-up sensors OR for sending events in the cache.
- int ret = looper->addFd(mChannel->getSendFd(), 0, looper_flags, this, NULL);
- if (ret == 1) {
- ALOGD_IF(DEBUG_CONNECTIONS, "%p addFd fd=%d", this, mChannel->getSendFd());
- mHasLooperCallbacks = true;
- } else {
- ALOGE("Looper::addFd failed ret=%d fd=%d", ret, mChannel->getSendFd());
- }
-}
-
-void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
- Mutex::Autolock _l(mConnectionLock);
- ssize_t index = mSensorInfo.indexOfKey(handle);
- if (index >= 0) {
- FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
- flushInfo.mPendingFlushEventsToSend++;
- }
-}
-
-status_t SensorService::SensorEventConnection::sendEvents(
- sensors_event_t const* buffer, size_t numEvents,
- sensors_event_t* scratch,
- SensorEventConnection const * const * mapFlushEventsToConnections) {
- // filter out events not for this connection
- int count = 0;
- Mutex::Autolock _l(mConnectionLock);
- if (scratch) {
- size_t i=0;
- while (i<numEvents) {
- int32_t sensor_handle = buffer[i].sensor;
- if (buffer[i].type == SENSOR_TYPE_META_DATA) {
- ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
- buffer[i].meta_data.sensor);
- // Setting sensor_handle to the correct sensor to ensure the sensor events per
- // connection are filtered correctly. buffer[i].sensor is zero for meta_data
- // events.
- sensor_handle = buffer[i].meta_data.sensor;
- }
- ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
- // Check if this connection has registered for this sensor. If not continue to the
- // next sensor_event.
- if (index < 0) {
- ++i;
- continue;
- }
-
- FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
- // Check if there is a pending flush_complete event for this sensor on this connection.
- if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
- this == mapFlushEventsToConnections[i]) {
- flushInfo.mFirstFlushPending = false;
- ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
- buffer[i].meta_data.sensor);
- ++i;
- continue;
- }
-
- // If there is a pending flush complete event for this sensor on this connection,
- // ignore the event and proceed to the next.
- if (flushInfo.mFirstFlushPending) {
- ++i;
- continue;
- }
-
- do {
- // Keep copying events into the scratch buffer as long as they are regular
- // sensor_events are from the same sensor_handle OR they are flush_complete_events
- // from the same sensor_handle AND the current connection is mapped to the
- // corresponding flush_complete_event.
- if (buffer[i].type == SENSOR_TYPE_META_DATA) {
- if (this == mapFlushEventsToConnections[i]) {
- scratch[count++] = buffer[i];
- }
- ++i;
- } else {
- // Regular sensor event, just copy it to the scratch buffer.
- scratch[count++] = buffer[i++];
- }
- } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
- buffer[i].type != SENSOR_TYPE_META_DATA) ||
- (buffer[i].type == SENSOR_TYPE_META_DATA &&
- buffer[i].meta_data.sensor == sensor_handle)));
- }
- } else {
- scratch = const_cast<sensors_event_t *>(buffer);
- count = numEvents;
- }
-
- sendPendingFlushEventsLocked();
- // Early return if there are no events for this connection.
- if (count == 0) {
- return status_t(NO_ERROR);
- }
-
-#if DEBUG_CONNECTIONS
- mEventsReceived += count;
-#endif
- 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));
- }
- return status_t(NO_ERROR);
- }
-
- int index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
- if (index_wake_up_event >= 0) {
- scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
- ++mWakeLockRefCount;
-#if DEBUG_CONNECTIONS
- ++mTotalAcksNeeded;
-#endif
- }
-
- // NOTE: ASensorEvent and sensors_event_t are the same type.
- ssize_t size = SensorEventQueue::write(mChannel,
- reinterpret_cast<ASensorEvent const*>(scratch), count);
- if (size < 0) {
- // Write error, copy events to local cache.
- if (index_wake_up_event >= 0) {
- // If there was a wake_up sensor_event, reset the flag.
- scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
- if (mWakeLockRefCount > 0) {
- --mWakeLockRefCount;
- }
-#if DEBUG_CONNECTIONS
- --mTotalAcksNeeded;
-#endif
- }
- if (mEventCache == NULL) {
- mMaxCacheSize = computeMaxCacheSizeLocked();
- mEventCache = new sensors_event_t[mMaxCacheSize];
- mCacheSize = 0;
- }
- memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
- mCacheSize += count;
-
- // Add this file descriptor to the looper to get a callback when this fd is available for
- // writing.
- updateLooperRegistrationLocked(mService->getLooper());
- return size;
- }
-
-#if DEBUG_CONNECTIONS
- if (size > 0) {
- mEventsSent += count;
- }
-#endif
-
- return size < 0 ? status_t(size) : status_t(NO_ERROR);
-}
-
-void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
- int count) {
- sensors_event_t *eventCache_new;
- const int new_cache_size = computeMaxCacheSizeLocked();
- // Allocate new cache, copy over events from the old cache & scratch, free up memory.
- eventCache_new = new sensors_event_t[new_cache_size];
- memcpy(eventCache_new, mEventCache, mCacheSize * sizeof(sensors_event_t));
- memcpy(&eventCache_new[mCacheSize], scratch, count * sizeof(sensors_event_t));
-
- ALOGD_IF(DEBUG_CONNECTIONS, "reAllocateCacheLocked maxCacheSize=%d %d", mMaxCacheSize,
- new_cache_size);
-
- delete mEventCache;
- mEventCache = eventCache_new;
- mCacheSize += count;
- mMaxCacheSize = new_cache_size;
-}
-
-void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
- ASensorEvent flushCompleteEvent;
- memset(&flushCompleteEvent, 0, sizeof(flushCompleteEvent));
- flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
- // Loop through all the sensors for this connection and check if there are any pending
- // flush complete events to be sent.
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
- while (flushInfo.mPendingFlushEventsToSend > 0) {
- const int sensor_handle = mSensorInfo.keyAt(i);
- flushCompleteEvent.meta_data.sensor = sensor_handle;
- bool wakeUpSensor = mService->getSensorFromHandle(sensor_handle).isWakeUpSensor();
- if (wakeUpSensor) {
- ++mWakeLockRefCount;
- flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
- }
- ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
- if (size < 0) {
- if (wakeUpSensor) --mWakeLockRefCount;
- return;
- }
- ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
- flushCompleteEvent.meta_data.sensor);
- flushInfo.mPendingFlushEventsToSend--;
- }
- }
-}
-
-void SensorService::SensorEventConnection::writeToSocketFromCache() {
- // At a time write at most half the size of the receiver buffer in SensorEventQueue OR
- // half the size of the socket buffer allocated in BitTube whichever is smaller.
- const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
- int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
- Mutex::Autolock _l(mConnectionLock);
- // Send pending flush complete events (if any)
- sendPendingFlushEventsLocked();
- for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
- const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
- int index_wake_up_event =
- findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
- if (index_wake_up_event >= 0) {
- mEventCache[index_wake_up_event + numEventsSent].flags |=
- WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
- ++mWakeLockRefCount;
-#if DEBUG_CONNECTIONS
- ++mTotalAcksNeeded;
-#endif
- }
-
- ssize_t size = SensorEventQueue::write(mChannel,
- reinterpret_cast<ASensorEvent const*>(mEventCache + numEventsSent),
- numEventsToWrite);
- if (size < 0) {
- if (index_wake_up_event >= 0) {
- // If there was a wake_up sensor_event, reset the flag.
- mEventCache[index_wake_up_event + numEventsSent].flags &=
- ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
- if (mWakeLockRefCount > 0) {
- --mWakeLockRefCount;
- }
-#if DEBUG_CONNECTIONS
- --mTotalAcksNeeded;
-#endif
- }
- memmove(mEventCache, &mEventCache[numEventsSent],
- (mCacheSize - numEventsSent) * sizeof(sensors_event_t));
- ALOGD_IF(DEBUG_CONNECTIONS, "wrote %d events from cache size==%d ",
- numEventsSent, mCacheSize);
- mCacheSize -= numEventsSent;
- return;
- }
- numEventsSent += numEventsToWrite;
-#if DEBUG_CONNECTIONS
- mEventsSentFromCache += numEventsToWrite;
-#endif
- }
- ALOGD_IF(DEBUG_CONNECTIONS, "wrote all events from cache size=%d ", mCacheSize);
- // All events from the cache have been sent. Reset cache size to zero.
- mCacheSize = 0;
- // There are no more events in the cache. We don't need to poll for write on the fd.
- // Update Looper registration.
- updateLooperRegistrationLocked(mService->getLooper());
-}
-
-void SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
- sensors_event_t const* scratch, const int numEventsDropped) {
- ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
- // Count flushComplete events in the events that are about to the dropped. These will be sent
- // separately before the next batch of events.
- for (int j = 0; j < numEventsDropped; ++j) {
- if (scratch[j].type == SENSOR_TYPE_META_DATA) {
- FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
- flushInfo.mPendingFlushEventsToSend++;
- ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
- flushInfo.mPendingFlushEventsToSend);
- }
- }
- return;
-}
-
-int SensorService::SensorEventConnection::findWakeUpSensorEventLocked(
- sensors_event_t const* scratch, const int count) {
- for (int i = 0; i < count; ++i) {
- if (mService->isWakeUpSensorEvent(scratch[i])) {
- return i;
- }
- }
- return -1;
-}
-
-sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
-{
- return mChannel;
-}
-
-status_t SensorService::SensorEventConnection::enableDisable(
- int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
- int reservedFlags)
-{
- status_t err;
- if (enabled) {
- err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
- reservedFlags, mOpPackageName);
-
- } else {
- err = mService->disable(this, handle);
- }
- return err;
-}
-
-status_t SensorService::SensorEventConnection::setEventRate(
- int handle, nsecs_t samplingPeriodNs)
-{
- return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
-}
-
-status_t SensorService::SensorEventConnection::flush() {
- return mService->flushSensor(this, mOpPackageName);
-}
-
-int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) {
- if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) {
- {
- // If the Looper encounters some error, set the flag mDead, reset mWakeLockRefCount,
- // and remove the fd from Looper. Call checkWakeLockState to know if SensorService
- // can release the wake-lock.
- ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
- Mutex::Autolock _l(mConnectionLock);
- mDead = true;
- mWakeLockRefCount = 0;
- updateLooperRegistrationLocked(mService->getLooper());
- }
- mService->checkWakeLockState();
- if (mDataInjectionMode) {
- // If the Looper has encountered some error in data injection mode, reset SensorService
- // back to normal mode.
- mService->resetToNormalMode();
- mDataInjectionMode = false;
- }
- return 1;
- }
-
- if (events & ALOOPER_EVENT_INPUT) {
- unsigned char buf[sizeof(sensors_event_t)];
- ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
- {
- Mutex::Autolock _l(mConnectionLock);
- if (numBytesRead == sizeof(sensors_event_t)) {
- if (!mDataInjectionMode) {
- ALOGE("Data injected in normal mode, dropping event"
- "package=%s uid=%d", mPackageName.string(), mUid);
- // Unregister call backs.
- return 0;
- }
- SensorDevice& dev(SensorDevice::getInstance());
- sensors_event_t sensor_event;
- memset(&sensor_event, 0, sizeof(sensor_event));
- memcpy(&sensor_event, buf, sizeof(sensors_event_t));
- Sensor sensor = mService->getSensorFromHandle(sensor_event.sensor);
- sensor_event.type = sensor.getType();
- dev.injectSensorData(&sensor_event);
-#if DEBUG_CONNECTIONS
- ++mEventsReceived;
-#endif
- } else if (numBytesRead == sizeof(uint32_t)) {
- uint32_t numAcks = 0;
- memcpy(&numAcks, buf, numBytesRead);
- // Sanity check to ensure there are no read errors in recv, numAcks is always
- // within the range and not zero. If any of the above don't hold reset
- // mWakeLockRefCount to zero.
- if (numAcks > 0 && numAcks < mWakeLockRefCount) {
- mWakeLockRefCount -= numAcks;
- } else {
- mWakeLockRefCount = 0;
- }
-#if DEBUG_CONNECTIONS
- mTotalAcksReceived += numAcks;
-#endif
- } else {
- // Read error, reset wakelock refcount.
- mWakeLockRefCount = 0;
- }
- }
- // Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
- // here as checkWakeLockState() will need it.
- if (mWakeLockRefCount == 0) {
- mService->checkWakeLockState();
- }
- // continue getting callbacks.
- return 1;
- }
-
- if (events & ALOOPER_EVENT_OUTPUT) {
- // send sensor data that is stored in mEventCache for this connection.
- mService->sendEventsFromCache(this);
- }
- return 1;
-}
-
-int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
- size_t fifoWakeUpSensors = 0;
- size_t fifoNonWakeUpSensors = 0;
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const Sensor& sensor = mService->getSensorFromHandle(mSensorInfo.keyAt(i));
- if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) {
- // Each sensor has a reserved fifo. Sum up the fifo sizes for all wake up sensors and
- // non wake_up sensors.
- if (sensor.isWakeUpSensor()) {
- fifoWakeUpSensors += sensor.getFifoReservedEventCount();
- } else {
- fifoNonWakeUpSensors += sensor.getFifoReservedEventCount();
- }
- } else {
- // Shared fifo. Compute the max of the fifo sizes for wake_up and non_wake up sensors.
- if (sensor.isWakeUpSensor()) {
- fifoWakeUpSensors = fifoWakeUpSensors > sensor.getFifoMaxEventCount() ?
- fifoWakeUpSensors : sensor.getFifoMaxEventCount();
-
- } else {
- fifoNonWakeUpSensors = fifoNonWakeUpSensors > sensor.getFifoMaxEventCount() ?
- fifoNonWakeUpSensors : sensor.getFifoMaxEventCount();
-
- }
- }
- }
- if (fifoWakeUpSensors + fifoNonWakeUpSensors == 0) {
- // It is extremely unlikely that there is a write failure in non batch mode. Return a cache
- // size that is equal to that of the batch mode.
- // ALOGW("Write failure in non-batch mode");
- return MAX_SOCKET_BUFFER_SIZE_BATCHED/sizeof(sensors_event_t);
- }
- return fifoWakeUpSensors + fifoNonWakeUpSensors;
-}
-
-// ---------------------------------------------------------------------------
}; // namespace android