Merge "Add an installd command to mark the end of boot." into lmp-mr1-dev
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index 5effd10..01b6ff4 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -44,6 +44,7 @@
// The default value of mBuf, used to indicate this doesn't correspond to a slot.
enum { INVALID_BUFFER_SLOT = -1 };
BufferItem();
+ ~BufferItem();
operator IGraphicBufferConsumer::BufferItem() const;
static const char* scalingModeName(uint32_t scalingMode);
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 3297b10..1188837 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -62,7 +62,7 @@
public:
ProxyConsumerListener(const wp<ConsumerListener>& consumerListener);
virtual ~ProxyConsumerListener();
- virtual void onFrameAvailable();
+ virtual void onFrameAvailable(const android::BufferItem& item);
virtual void onBuffersReleased();
virtual void onSidebandStreamChanged();
private:
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index c619a11..ed1056a 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -203,6 +203,16 @@
// since the previous buffer might have already been acquired.
sp<Fence> mLastQueueBufferFence;
+ // Take-a-ticket system for ensuring that onFrame* callbacks are called in
+ // the order that frames are queued. While the BufferQueue lock
+ // (mCore->mMutex) is held, a ticket is retained by the producer. After
+ // dropping the BufferQueue lock, the producer must wait on the condition
+ // variable until the current callback ticket matches its retained ticket.
+ Mutex mCallbackMutex;
+ int mNextCallbackTicket; // Protected by mCore->mMutex
+ int mCurrentCallbackTicket; // Protected by mCallbackMutex
+ Condition mCallbackCondition;
+
}; // class BufferQueueProducer
} // namespace android
diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h
index 100bb26..f7ab5ac 100644
--- a/include/gui/ConsumerBase.h
+++ b/include/gui/ConsumerBase.h
@@ -46,7 +46,7 @@
//
// This is called without any lock held and can be called concurrently
// by multiple threads.
- virtual void onFrameAvailable() = 0;
+ virtual void onFrameAvailable(const BufferItem& item) = 0;
};
virtual ~ConsumerBase();
@@ -106,7 +106,7 @@
// the ConsumerBase implementation must be called from the derived class.
// The ConsumerBase version of onSidebandStreamChanged does nothing and can
// be overriden by derived classes if they want the notification.
- virtual void onFrameAvailable();
+ virtual void onFrameAvailable(const BufferItem& item);
virtual void onBuffersReleased();
virtual void onSidebandStreamChanged();
diff --git a/include/gui/IConsumerListener.h b/include/gui/IConsumerListener.h
index 260099e..3f39799 100644
--- a/include/gui/IConsumerListener.h
+++ b/include/gui/IConsumerListener.h
@@ -28,6 +28,8 @@
namespace android {
// ----------------------------------------------------------------------------
+class BufferItem;
+
// ConsumerListener is the interface through which the BufferQueue notifies
// the consumer of events that the consumer may wish to react to. Because
// the consumer will generally have a mutex that is locked during calls from
@@ -43,11 +45,24 @@
// frame becomes available for consumption. This means that frames that
// are queued while in asynchronous mode only trigger the callback if no
// previous frames are pending. Frames queued while in synchronous mode
- // always trigger the callback.
+ // always trigger the callback. The item passed to the callback will contain
+ // all of the information about the queued frame except for its
+ // GraphicBuffer pointer, which will always be null.
//
// This is called without any lock held and can be called concurrently
// by multiple threads.
- virtual void onFrameAvailable() = 0; /* Asynchronous */
+ virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */
+
+ // onFrameReplaced is called from queueBuffer if the frame being queued is
+ // replacing an existing slot in the queue. Any call to queueBuffer that
+ // doesn't call onFrameAvailable will call this callback instead. The item
+ // passed to the callback will contain all of the information about the
+ // queued frame except for its GraphicBuffer pointer, which will always be
+ // null.
+ //
+ // This is called without any lock held and can be called concurrently
+ // by multiple threads.
+ virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */
// onBuffersReleased is called to notify the buffer consumer that the
// BufferQueue has released its references to one or more GraphicBuffers
diff --git a/include/gui/StreamSplitter.h b/include/gui/StreamSplitter.h
index f927953..8f47eb4 100644
--- a/include/gui/StreamSplitter.h
+++ b/include/gui/StreamSplitter.h
@@ -74,7 +74,7 @@
// can block if there are too many outstanding buffers. If it blocks, it
// will resume when onBufferReleasedByOutput releases a buffer back to the
// input.
- virtual void onFrameAvailable();
+ virtual void onFrameAvailable(const BufferItem& item);
// From IConsumerListener
// We don't care about released buffers because we detach each buffer as
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
index d3fa43e..e6fc791 100644
--- a/libs/gui/BufferItem.cpp
+++ b/libs/gui/BufferItem.cpp
@@ -36,6 +36,8 @@
mCrop.makeInvalid();
}
+BufferItem::~BufferItem() {}
+
BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
IGraphicBufferConsumer::BufferItem bufferItem;
bufferItem.mGraphicBuffer = mGraphicBuffer;
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index c49a886..61fd8c4 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -31,10 +31,11 @@
BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
-void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
+void BufferQueue::ProxyConsumerListener::onFrameAvailable(
+ const android::BufferItem& item) {
sp<ConsumerListener> listener(mConsumerListener.promote());
if (listener != NULL) {
- listener->onFrameAvailable();
+ listener->onFrameAvailable(item);
}
}
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 03bd4fd..16b9747 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -39,7 +39,11 @@
mSlots(core->mSlots),
mConsumerName(),
mStickyTransform(0),
- mLastQueueBufferFence(Fence::NO_FENCE) {}
+ mLastQueueBufferFence(Fence::NO_FENCE),
+ mCallbackMutex(),
+ mNextCallbackTicket(0),
+ mCurrentCallbackTicket(0),
+ mCallbackCondition() {}
BufferQueueProducer::~BufferQueueProducer() {}
@@ -537,7 +541,10 @@
return BAD_VALUE;
}
- sp<IConsumerListener> listener;
+ sp<IConsumerListener> frameAvailableListener;
+ sp<IConsumerListener> frameReplacedListener;
+ int callbackTicket = 0;
+ BufferItem item;
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
@@ -593,7 +600,6 @@
++mCore->mFrameCounter;
mSlots[slot].mFrameNumber = mCore->mFrameCounter;
- BufferItem item;
item.mAcquireCalled = mSlots[slot].mAcquireCalled;
item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
item.mCrop = crop;
@@ -614,7 +620,7 @@
// When the queue is empty, we can ignore mDequeueBufferCannotBlock
// and simply queue this buffer
mCore->mQueue.push_back(item);
- listener = mCore->mConsumerListener;
+ frameAvailableListener = mCore->mConsumerListener;
} else {
// When the queue is not empty, we need to look at the front buffer
// state to see if we need to replace it
@@ -630,9 +636,10 @@
}
// Overwrite the droppable buffer with the incoming one
*front = item;
+ frameReplacedListener = mCore->mConsumerListener;
} else {
mCore->mQueue.push_back(item);
- listener = mCore->mConsumerListener;
+ frameAvailableListener = mCore->mConsumerListener;
}
}
@@ -643,6 +650,9 @@
mCore->mTransformHint, mCore->mQueue.size());
ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
+
+ // Take a ticket for the callback functions
+ callbackTicket = mNextCallbackTicket++;
} // Autolock scope
// Wait without lock held
@@ -654,9 +664,27 @@
mLastQueueBufferFence = fence;
}
- // Call back without lock held
- if (listener != NULL) {
- listener->onFrameAvailable();
+ // Don't send the GraphicBuffer through the callback, and don't send
+ // the slot number, since the consumer shouldn't need it
+ item.mGraphicBuffer.clear();
+ item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
+
+ // Call back without the main BufferQueue lock held, but with the callback
+ // lock held so we can ensure that callbacks occur in order
+ {
+ Mutex::Autolock lock(mCallbackMutex);
+ while (callbackTicket != mCurrentCallbackTicket) {
+ mCallbackCondition.wait(mCallbackMutex);
+ }
+
+ if (frameAvailableListener != NULL) {
+ frameAvailableListener->onFrameAvailable(item);
+ } else if (frameReplacedListener != NULL) {
+ frameReplacedListener->onFrameReplaced(item);
+ }
+
+ ++mCurrentCallbackTicket;
+ mCallbackCondition.broadcast();
}
return NO_ERROR;
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index f19b6c7..210e98e 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -98,7 +98,7 @@
mSlots[slotIndex].mFrameNumber = 0;
}
-void ConsumerBase::onFrameAvailable() {
+void ConsumerBase::onFrameAvailable(const BufferItem& item) {
CB_LOGV("onFrameAvailable");
sp<FrameAvailableListener> listener;
@@ -109,7 +109,7 @@
if (listener != NULL) {
CB_LOGV("actually calling onFrameAvailable");
- listener->onFrameAvailable();
+ listener->onFrameAvailable(item);
}
}
diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp
index 4ccf0ac..409dfe4 100644
--- a/libs/gui/IConsumerListener.cpp
+++ b/libs/gui/IConsumerListener.cpp
@@ -21,6 +21,7 @@
#include <binder/Parcel.h>
#include <gui/IConsumerListener.h>
+#include <gui/BufferItem.h>
// ---------------------------------------------------------------------------
namespace android {
@@ -39,9 +40,10 @@
: BpInterface<IConsumerListener>(impl) {
}
- virtual void onFrameAvailable() {
+ virtual void onFrameAvailable(const BufferItem& item) {
Parcel data, reply;
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
+ data.write(item);
remote()->transact(ON_FRAME_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -66,18 +68,20 @@
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
- case ON_FRAME_AVAILABLE:
+ case ON_FRAME_AVAILABLE: {
CHECK_INTERFACE(IConsumerListener, data, reply);
- onFrameAvailable();
- return NO_ERROR;
- case ON_BUFFER_RELEASED:
+ BufferItem item;
+ data.read(item);
+ onFrameAvailable(item);
+ return NO_ERROR; }
+ case ON_BUFFER_RELEASED: {
CHECK_INTERFACE(IConsumerListener, data, reply);
onBuffersReleased();
- return NO_ERROR;
- case ON_SIDEBAND_STREAM_CHANGED:
+ return NO_ERROR; }
+ case ON_SIDEBAND_STREAM_CHANGED: {
CHECK_INTERFACE(IConsumerListener, data, reply);
onSidebandStreamChanged();
- return NO_ERROR;
+ return NO_ERROR; }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp
index 771b263..5f39905 100644
--- a/libs/gui/StreamSplitter.cpp
+++ b/libs/gui/StreamSplitter.cpp
@@ -98,7 +98,7 @@
mInput->setConsumerName(name);
}
-void StreamSplitter::onFrameAvailable() {
+void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) {
ATRACE_CALL();
Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index c781366..96de11f 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -67,7 +67,7 @@
};
struct DummyConsumer : public BnConsumerListener {
- virtual void onFrameAvailable() {}
+ virtual void onFrameAvailable(const BufferItem& /* item */) {}
virtual void onBuffersReleased() {}
virtual void onSidebandStreamChanged() {}
};
diff --git a/libs/gui/tests/DisconnectWaiter.h b/libs/gui/tests/DisconnectWaiter.h
index 56e96c2..6e6915b 100644
--- a/libs/gui/tests/DisconnectWaiter.h
+++ b/libs/gui/tests/DisconnectWaiter.h
@@ -44,7 +44,7 @@
mPendingFrames--;
}
- virtual void onFrameAvailable() {
+ virtual void onFrameAvailable(const BufferItem& /* item */) {
Mutex::Autolock lock(mMutex);
mPendingFrames++;
mFrameCondition.signal();
diff --git a/libs/gui/tests/FrameWaiter.h b/libs/gui/tests/FrameWaiter.h
index bdedba6..f78fa00 100644
--- a/libs/gui/tests/FrameWaiter.h
+++ b/libs/gui/tests/FrameWaiter.h
@@ -35,7 +35,7 @@
mPendingFrames--;
}
- virtual void onFrameAvailable() {
+ virtual void onFrameAvailable(const BufferItem& /* item */) {
Mutex::Autolock lock(mMutex);
mPendingFrames++;
mCondition.signal();
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index aadfe61..8d5fd8f 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -65,7 +65,7 @@
}; // namespace anonymous
struct DummyConsumer : public BnConsumerListener {
- virtual void onFrameAvailable() {}
+ virtual void onFrameAvailable(const BufferItem& /* item */) {}
virtual void onBuffersReleased() {}
virtual void onSidebandStreamChanged() {}
};
diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp
index 32ec90d..4e63a6f 100644
--- a/libs/gui/tests/StreamSplitter_test.cpp
+++ b/libs/gui/tests/StreamSplitter_test.cpp
@@ -46,7 +46,7 @@
};
struct DummyListener : public BnConsumerListener {
- virtual void onFrameAvailable() {}
+ virtual void onFrameAvailable(const BufferItem& /* item */) {}
virtual void onBuffersReleased() {}
virtual void onSidebandStreamChanged() {}
};
diff --git a/libs/gui/tests/SurfaceTextureGLThreadToGL.h b/libs/gui/tests/SurfaceTextureGLThreadToGL.h
index 6410516..14e42ac 100644
--- a/libs/gui/tests/SurfaceTextureGLThreadToGL.h
+++ b/libs/gui/tests/SurfaceTextureGLThreadToGL.h
@@ -130,7 +130,7 @@
}
// This should be called by GLConsumer on the producer thread.
- virtual void onFrameAvailable() {
+ virtual void onFrameAvailable(const BufferItem& /* item */) {
Mutex::Autolock lock(mMutex);
ALOGV("+onFrameAvailable");
mFrameAvailable = true;
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index a4364c6..d69a275 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -101,7 +101,7 @@
EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
struct DummyConsumer : public BnConsumerListener {
- virtual void onFrameAvailable() {}
+ virtual void onFrameAvailable(const BufferItem& /* item */) {}
virtual void onBuffersReleased() {}
virtual void onSidebandStreamChanged() {}
};
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index dc8fa64..c316ef6 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -191,6 +191,8 @@
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 @@
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 @@
// 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 @@
}
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
- mWakeLockAcquired = true;
+ setWakeLockAcquiredLocked(true);
}
recordLastValueLocked(mSensorEventBuffer, count);
@@ -522,8 +512,7 @@
}
if (mWakeLockAcquired && !needsWakeLock) {
- release_wake_lock(WAKE_LOCK_NAME);
- mWakeLockAcquired = false;
+ setWakeLockAcquiredLocked(false);
}
} while (!Thread::exitPending());
@@ -536,11 +525,52 @@
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");
+ sp<Looper> looper = mService->getLooper();
do {
- sp<Looper> looper = mService->getLooper();
- looper->pollOnce(-1);
+ 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 @@
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 @@
}
}
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 @@
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 @@
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::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 @@
}
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;
}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 5e3eeb5..8719487 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -101,7 +101,7 @@
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 @@
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 @@
// 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 @@
// supported or not.
uint32_t mSocketBufferSize;
sp<Looper> mLooper;
+ sp<SensorEventAckReceiver> mAckReceiver;
// protected by mLock
mutable Mutex mLock;
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index b767983..22d3cec 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -122,7 +122,7 @@
}
// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
-void FramebufferSurface::onFrameAvailable() {
+void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
sp<GraphicBuffer> buf;
sp<Fence> acquireFence;
status_t err = nextBuffer(buf, acquireFence);
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index d0bf22b..8605862 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -56,7 +56,7 @@
private:
virtual ~FramebufferSurface() { }; // this class cannot be overloaded
- virtual void onFrameAvailable();
+ virtual void onFrameAvailable(const BufferItem& item);
virtual void freeBufferLocked(int slotIndex);
virtual void dumpLocked(String8& result, const char* prefix) const;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f6ad503..acc2775 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -159,7 +159,7 @@
}
}
-void Layer::onFrameAvailable() {
+void Layer::onFrameAvailable(const BufferItem& /* item */) {
android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 1f8eff0..e2100fc 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -330,7 +330,7 @@
private:
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
- virtual void onFrameAvailable();
+ virtual void onFrameAvailable(const BufferItem& item);
virtual void onSidebandStreamChanged();
void commitTransaction();