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:
commit
686edee8e9
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue