Add a timeout for releasing SensorService wake_lock.
If SensorService is holding a wake_lock and there are no acknowledgements from ANY app within 5 seconds, release the wake_lock and reset the wake_lock refcounts for all connections. Bug: 16874240 Change-Id: I5e950dd393c20173c439cbd5a4ba614ee09d61f4
This commit is contained in:
parent
70ec294153
commit
b4373ac9f5
@ -191,6 +191,8 @@ void SensorService::onFirstRef()
|
||||
mSensorEventScratch = new sensors_event_t[minBufferSize];
|
||||
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
|
||||
|
||||
mAckReceiver = new SensorEventAckReceiver(this);
|
||||
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
||||
mInitCheck = NO_ERROR;
|
||||
run("SensorService", PRIORITY_URGENT_DISPLAY);
|
||||
}
|
||||
@ -386,8 +388,6 @@ bool SensorService::threadLoop()
|
||||
SensorDevice& device(SensorDevice::getInstance());
|
||||
const size_t vcount = mVirtualSensorList.size();
|
||||
|
||||
SensorEventAckReceiver sender(this);
|
||||
sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
||||
const int halVersion = device.getHalDeviceVersion();
|
||||
do {
|
||||
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
|
||||
// cleanup. So copy all the strongPointers to a vector before the lock is acquired.
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@ -433,8 +424,7 @@ bool SensorService::threadLoop()
|
||||
}
|
||||
|
||||
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
|
||||
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
|
||||
mWakeLockAcquired = true;
|
||||
setWakeLockAcquiredLocked(true);
|
||||
}
|
||||
recordLastValueLocked(mSensorEventBuffer, count);
|
||||
|
||||
@ -522,8 +512,7 @@ bool SensorService::threadLoop()
|
||||
}
|
||||
|
||||
if (mWakeLockAcquired && !needsWakeLock) {
|
||||
release_wake_lock(WAKE_LOCK_NAME);
|
||||
mWakeLockAcquired = false;
|
||||
setWakeLockAcquiredLocked(false);
|
||||
}
|
||||
} while (!Thread::exitPending());
|
||||
|
||||
@ -536,11 +525,52 @@ sp<Looper> SensorService::getLooper() const {
|
||||
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() {
|
||||
ALOGD("new thread SensorEventAckReceiver");
|
||||
do {
|
||||
sp<Looper> looper = mService->getLooper();
|
||||
looper->pollOnce(-1);
|
||||
do {
|
||||
bool wakeLockAcquired = mService->isWakeLockAcquired();
|
||||
int timeout = -1;
|
||||
if (wakeLockAcquired) timeout = 5000;
|
||||
int ret = looper->pollOnce(timeout);
|
||||
if (ret == ALOOPER_POLL_TIMEOUT) {
|
||||
mService->resetAllWakeLockRefCounts();
|
||||
}
|
||||
} while(!Thread::exitPending());
|
||||
return false;
|
||||
}
|
||||
@ -714,10 +744,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
||||
sensors_event_t& event(mLastEventSeen.editValueFor(handle));
|
||||
if (event.version == sizeof(sensors_event_t)) {
|
||||
if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
|
||||
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
|
||||
mWakeLockAcquired = true;
|
||||
ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock for on_change sensor %s",
|
||||
WAKE_LOCK_NAME);
|
||||
setWakeLockAcquiredLocked(true);
|
||||
}
|
||||
connection->sendEvents(&event, 1, NULL);
|
||||
if (!connection->needsWakeLock() && mWakeLockAcquired) {
|
||||
@ -922,8 +949,26 @@ void SensorService::checkWakeLockStateLocked() {
|
||||
}
|
||||
}
|
||||
if (releaseLock) {
|
||||
release_wake_lock(WAKE_LOCK_NAME);
|
||||
mWakeLockAcquired = false;
|
||||
setWakeLockAcquiredLocked(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;
|
||||
}
|
||||
|
||||
void SensorService::SensorEventConnection::resetWakeLockRefCount() {
|
||||
Mutex::Autolock _l(mConnectionLock);
|
||||
mWakeLockRefCount = 0;
|
||||
}
|
||||
|
||||
void SensorService::SensorEventConnection::dump(String8& result) {
|
||||
Mutex::Autolock _l(mConnectionLock);
|
||||
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) {
|
||||
const int sensor_handle = mSensorInfo.keyAt(i);
|
||||
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;
|
||||
}
|
||||
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 ",
|
||||
@ -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
|
||||
// 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;) {
|
||||
@ -1503,9 +1557,8 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
|
||||
}
|
||||
|
||||
if (events & ALOOPER_EVENT_OUTPUT) {
|
||||
// send sensor data that is stored in mEventCache.
|
||||
Mutex::Autolock _l(mConnectionLock);
|
||||
writeToSocketFromCacheLocked();
|
||||
// send sensor data that is stored in mEventCache for this connection.
|
||||
mService->sendEventsFromCache(this);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ class SensorService :
|
||||
void sendPendingFlushEventsLocked();
|
||||
|
||||
// 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
|
||||
// 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 dump(String8& result);
|
||||
bool needsWakeLock();
|
||||
void resetWakeLockRefCount();
|
||||
|
||||
uid_t getUid() const { return mUid; }
|
||||
};
|
||||
@ -230,12 +231,29 @@ class SensorService :
|
||||
// corresponding applications, if yes the wakelock is released.
|
||||
void checkWakeLockState();
|
||||
void checkWakeLockStateLocked();
|
||||
bool isWakeLockAcquired();
|
||||
bool isWakeUpSensorEvent(const sensors_event_t& event) const;
|
||||
|
||||
SensorRecord * getSensorRecord(int handle);
|
||||
|
||||
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
|
||||
Vector<Sensor> mSensorList;
|
||||
Vector<Sensor> mUserSensorListDebug;
|
||||
@ -247,6 +265,7 @@ class SensorService :
|
||||
// supported or not.
|
||||
uint32_t mSocketBufferSize;
|
||||
sp<Looper> mLooper;
|
||||
sp<SensorEventAckReceiver> mAckReceiver;
|
||||
|
||||
// protected by mLock
|
||||
mutable Mutex mLock;
|
||||
|
Loading…
Reference in New Issue
Block a user