am a2614354: Merge "Add a timeout for releasing SensorService wake_lock." into lmp-mr1-dev

* commit 'a26143546e4665cc3b07d6527b63a2e4bb04fb9f':
  Add a timeout for releasing SensorService wake_lock.
This commit is contained in:
Aravind Akella 2014-11-07 22:01:03 +00:00 committed by Android Git Automerger
commit 686edee8e9
2 changed files with 102 additions and 30 deletions

View File

@ -191,6 +191,8 @@ void SensorService::onFirstRef()
mSensorEventScratch = new sensors_event_t[minBufferSize]; mSensorEventScratch = new sensors_event_t[minBufferSize];
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize]; mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
mInitCheck = NO_ERROR; mInitCheck = NO_ERROR;
run("SensorService", PRIORITY_URGENT_DISPLAY); run("SensorService", PRIORITY_URGENT_DISPLAY);
} }
@ -386,8 +388,6 @@ bool SensorService::threadLoop()
SensorDevice& device(SensorDevice::getInstance()); SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size(); const size_t vcount = mVirtualSensorList.size();
SensorEventAckReceiver sender(this);
sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
const int halVersion = device.getHalDeviceVersion(); const int halVersion = device.getHalDeviceVersion();
do { do {
ssize_t count = device.poll(mSensorEventBuffer, numEventMax); ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
@ -408,16 +408,7 @@ bool SensorService::threadLoop()
// result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for // 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. // cleanup. So copy all the strongPointers to a vector before the lock is acquired.
SortedVector< sp<SensorEventConnection> > activeConnections; SortedVector< sp<SensorEventConnection> > activeConnections;
{ populateActiveConnections(&activeConnections);
Mutex::Autolock _l(mLock);
for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
sp<SensorEventConnection> connection(mActiveConnections[i].promote());
if (connection != 0) {
activeConnections.add(connection);
}
}
}
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The // 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, // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
@ -433,8 +424,7 @@ bool SensorService::threadLoop()
} }
if (bufferHasWakeUpEvent && !mWakeLockAcquired) { if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); setWakeLockAcquiredLocked(true);
mWakeLockAcquired = true;
} }
recordLastValueLocked(mSensorEventBuffer, count); recordLastValueLocked(mSensorEventBuffer, count);
@ -522,8 +512,7 @@ bool SensorService::threadLoop()
} }
if (mWakeLockAcquired && !needsWakeLock) { if (mWakeLockAcquired && !needsWakeLock) {
release_wake_lock(WAKE_LOCK_NAME); setWakeLockAcquiredLocked(false);
mWakeLockAcquired = false;
} }
} while (!Thread::exitPending()); } while (!Thread::exitPending());
@ -536,11 +525,52 @@ sp<Looper> SensorService::getLooper() const {
return mLooper; return mLooper;
} }
void SensorService::resetAllWakeLockRefCounts() {
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
{
Mutex::Autolock _l(mLock);
for (size_t i=0 ; i < activeConnections.size(); ++i) {
if (activeConnections[i] != 0) {
activeConnections[i]->resetWakeLockRefCount();
}
}
setWakeLockAcquiredLocked(false);
}
}
void SensorService::setWakeLockAcquiredLocked(bool acquire) {
if (acquire) {
if (!mWakeLockAcquired) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
mWakeLockAcquired = true;
}
mLooper->wake();
} else {
if (mWakeLockAcquired) {
release_wake_lock(WAKE_LOCK_NAME);
mWakeLockAcquired = false;
}
}
}
bool SensorService::isWakeLockAcquired() {
Mutex::Autolock _l(mLock);
return mWakeLockAcquired;
}
bool SensorService::SensorEventAckReceiver::threadLoop() { bool SensorService::SensorEventAckReceiver::threadLoop() {
ALOGD("new thread SensorEventAckReceiver"); ALOGD("new thread SensorEventAckReceiver");
sp<Looper> looper = mService->getLooper();
do { do {
sp<Looper> looper = mService->getLooper(); bool wakeLockAcquired = mService->isWakeLockAcquired();
looper->pollOnce(-1); int timeout = -1;
if (wakeLockAcquired) timeout = 5000;
int ret = looper->pollOnce(timeout);
if (ret == ALOOPER_POLL_TIMEOUT) {
mService->resetAllWakeLockRefCounts();
}
} while(!Thread::exitPending()); } while(!Thread::exitPending());
return false; return false;
} }
@ -714,10 +744,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
sensors_event_t& event(mLastEventSeen.editValueFor(handle)); sensors_event_t& event(mLastEventSeen.editValueFor(handle));
if (event.version == sizeof(sensors_event_t)) { if (event.version == sizeof(sensors_event_t)) {
if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) { if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); setWakeLockAcquiredLocked(true);
mWakeLockAcquired = true;
ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock for on_change sensor %s",
WAKE_LOCK_NAME);
} }
connection->sendEvents(&event, 1, NULL); connection->sendEvents(&event, 1, NULL);
if (!connection->needsWakeLock() && mWakeLockAcquired) { if (!connection->needsWakeLock() && mWakeLockAcquired) {
@ -922,8 +949,26 @@ void SensorService::checkWakeLockStateLocked() {
} }
} }
if (releaseLock) { if (releaseLock) {
release_wake_lock(WAKE_LOCK_NAME); setWakeLockAcquiredLocked(false);
mWakeLockAcquired = false; }
}
void SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
Mutex::Autolock _l(mLock);
connection->writeToSocketFromCache();
if (connection->needsWakeLock()) {
setWakeLockAcquiredLocked(true);
}
}
void SensorService::populateActiveConnections(
SortedVector< sp<SensorEventConnection> >* activeConnections) {
Mutex::Autolock _l(mLock);
for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
sp<SensorEventConnection> connection(mActiveConnections[i].promote());
if (connection != 0) {
activeConnections->add(connection);
}
} }
} }
@ -1013,6 +1058,11 @@ bool SensorService::SensorEventConnection::needsWakeLock() {
return !mDead && mWakeLockRefCount > 0; return !mDead && mWakeLockRefCount > 0;
} }
void SensorService::SensorEventConnection::resetWakeLockRefCount() {
Mutex::Autolock _l(mConnectionLock);
mWakeLockRefCount = 0;
}
void SensorService::SensorEventConnection::dump(String8& result) { void SensorService::SensorEventConnection::dump(String8& result) {
Mutex::Autolock _l(mConnectionLock); Mutex::Autolock _l(mConnectionLock);
result.appendFormat("\t WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n", result.appendFormat("\t WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
@ -1334,11 +1384,14 @@ void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
while (flushInfo.mPendingFlushEventsToSend > 0) { while (flushInfo.mPendingFlushEventsToSend > 0) {
const int sensor_handle = mSensorInfo.keyAt(i); const int sensor_handle = mSensorInfo.keyAt(i);
flushCompleteEvent.meta_data.sensor = sensor_handle; flushCompleteEvent.meta_data.sensor = sensor_handle;
if (mService->getSensorFromHandle(sensor_handle).isWakeUpSensor()) { bool wakeUpSensor = mService->getSensorFromHandle(sensor_handle).isWakeUpSensor();
if (wakeUpSensor) {
++mWakeLockRefCount;
flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK; flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
} }
ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1); ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
if (size < 0) { if (size < 0) {
if (wakeUpSensor) --mWakeLockRefCount;
return; return;
} }
ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ", ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
@ -1348,11 +1401,12 @@ void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
} }
} }
void SensorService::SensorEventConnection::writeToSocketFromCacheLocked() { void SensorService::SensorEventConnection::writeToSocketFromCache() {
// At a time write at most half the size of the receiver buffer in SensorEventQueue OR // 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. // 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, const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2))); int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
Mutex::Autolock _l(mConnectionLock);
// Send pending flush complete events (if any) // Send pending flush complete events (if any)
sendPendingFlushEventsLocked(); sendPendingFlushEventsLocked();
for (int numEventsSent = 0; numEventsSent < mCacheSize;) { for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
@ -1503,9 +1557,8 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
} }
if (events & ALOOPER_EVENT_OUTPUT) { if (events & ALOOPER_EVENT_OUTPUT) {
// send sensor data that is stored in mEventCache. // send sensor data that is stored in mEventCache for this connection.
Mutex::Autolock _l(mConnectionLock); mService->sendEventsFromCache(this);
writeToSocketFromCacheLocked();
} }
return 1; return 1;
} }

View File

@ -101,7 +101,7 @@ class SensorService :
void sendPendingFlushEventsLocked(); void sendPendingFlushEventsLocked();
// Writes events from mEventCache to the socket. // Writes events from mEventCache to the socket.
void writeToSocketFromCacheLocked(); void writeToSocketFromCache();
// Compute the approximate cache size from the FIFO sizes of various sensors registered for // Compute the approximate cache size from the FIFO sizes of various sensors registered for
// this connection. Wake up and non-wake up sensors have separate FIFOs but FIFO may be // this connection. Wake up and non-wake up sensors have separate FIFOs but FIFO may be
@ -182,6 +182,7 @@ class SensorService :
void setFirstFlushPending(int32_t handle, bool value); void setFirstFlushPending(int32_t handle, bool value);
void dump(String8& result); void dump(String8& result);
bool needsWakeLock(); bool needsWakeLock();
void resetWakeLockRefCount();
uid_t getUid() const { return mUid; } uid_t getUid() const { return mUid; }
}; };
@ -230,12 +231,29 @@ class SensorService :
// corresponding applications, if yes the wakelock is released. // corresponding applications, if yes the wakelock is released.
void checkWakeLockState(); void checkWakeLockState();
void checkWakeLockStateLocked(); void checkWakeLockStateLocked();
bool isWakeLockAcquired();
bool isWakeUpSensorEvent(const sensors_event_t& event) const; bool isWakeUpSensorEvent(const sensors_event_t& event) const;
SensorRecord * getSensorRecord(int handle); SensorRecord * getSensorRecord(int handle);
sp<Looper> getLooper() const; sp<Looper> getLooper() const;
// Reset mWakeLockRefCounts for all SensorEventConnections to zero. This may happen if
// SensorService did not receive any acknowledgements from apps which have registered for
// wake_up sensors.
void resetAllWakeLockRefCounts();
// Acquire or release wake_lock. If wake_lock is acquired, set the timeout in the looper to
// 5 seconds and wake the looper.
void setWakeLockAcquiredLocked(bool acquire);
// Send events from the event cache for this particular connection.
void sendEventsFromCache(const sp<SensorEventConnection>& connection);
// Promote all weak referecences in mActiveConnections vector to strong references and add them
// to the output vector.
void populateActiveConnections(SortedVector< sp<SensorEventConnection> >* activeConnections);
// constants // constants
Vector<Sensor> mSensorList; Vector<Sensor> mSensorList;
Vector<Sensor> mUserSensorListDebug; Vector<Sensor> mUserSensorListDebug;
@ -247,6 +265,7 @@ class SensorService :
// supported or not. // supported or not.
uint32_t mSocketBufferSize; uint32_t mSocketBufferSize;
sp<Looper> mLooper; sp<Looper> mLooper;
sp<SensorEventAckReceiver> mAckReceiver;
// protected by mLock // protected by mLock
mutable Mutex mLock; mutable Mutex mLock;