Merge "Enable deferred input messages to be batched."

This commit is contained in:
Jeff Brown
2012-02-13 13:55:41 -08:00
committed by Android (Google) Code Review
2 changed files with 45 additions and 55 deletions

View File

@@ -297,10 +297,12 @@ public:
private: private:
sp<InputChannel> mChannel; sp<InputChannel> mChannel;
// State about an event that consume would have returned except that it had to // The current input message.
// return a completed batch first. Sequence number is non-zero if an event was deferred. InputMessage mMsg;
uint32_t mDeferredEventSeq;
MotionEvent mDeferredEvent; // True if mMsg contains a valid input message that was deferred from the previous
// call to consume and that still needs to be handled.
bool mMsgDeferred;
// Batched motion events per device and source. // Batched motion events per device and source.
struct Batch { struct Batch {

View File

@@ -334,7 +334,7 @@ status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandle
// --- InputConsumer --- // --- InputConsumer ---
InputConsumer::InputConsumer(const sp<InputChannel>& channel) : InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
mChannel(channel), mDeferredEventSeq(0) { mChannel(channel), mMsgDeferred(false) {
} }
InputConsumer::~InputConsumer() { InputConsumer::~InputConsumer() {
@@ -350,55 +350,44 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
*outSeq = 0; *outSeq = 0;
*outEvent = NULL; *outEvent = NULL;
// Report deferred event first, if we had to end a batch earlier than we expected
// during the previous time consume was called.
if (mDeferredEventSeq) {
MotionEvent* motionEvent = factory->createMotionEvent();
if (! motionEvent) return NO_MEMORY;
motionEvent->copyFrom(&mDeferredEvent, true /*keepHistory*/);
*outSeq = mDeferredEventSeq;
*outEvent = motionEvent;
mDeferredEventSeq = 0;
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed deferred event, seq=%u",
mChannel->getName().string(), *outSeq);
#endif
return OK;
}
// Fetch the next input message. // Fetch the next input message.
// Loop until an event can be returned or no additional events are received. // Loop until an event can be returned or no additional events are received.
while (!*outEvent) { while (!*outEvent) {
InputMessage msg; if (mMsgDeferred) {
status_t result = mChannel->receiveMessage(&msg); // mMsg contains a valid input message from the previous call to consume
if (result) { // that has not yet been processed.
// Consume the next batched event unless batches are being held for later. mMsgDeferred = false;
if (!mBatches.isEmpty() && (consumeBatches || result != WOULD_BLOCK)) { } else {
MotionEvent* motionEvent = factory->createMotionEvent(); // Receive a fresh message.
if (! motionEvent) return NO_MEMORY; status_t result = mChannel->receiveMessage(&mMsg);
if (result) {
// Consume the next batched event unless batches are being held for later.
if (!mBatches.isEmpty() && (consumeBatches || result != WOULD_BLOCK)) {
MotionEvent* motionEvent = factory->createMotionEvent();
if (! motionEvent) return NO_MEMORY;
const Batch& batch = mBatches.top(); const Batch& batch = mBatches.top();
motionEvent->copyFrom(&batch.event, true /*keepHistory*/); motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
*outSeq = batch.seq; *outSeq = batch.seq;
*outEvent = motionEvent; *outEvent = motionEvent;
mBatches.pop(); mBatches.pop();
#if DEBUG_TRANSPORT_ACTIONS #if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u", ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
mChannel->getName().string(), *outSeq); mChannel->getName().string(), *outSeq);
#endif #endif
break; break;
}
return result;
} }
return result;
} }
switch (msg.header.type) { switch (mMsg.header.type) {
case InputMessage::TYPE_KEY: { case InputMessage::TYPE_KEY: {
KeyEvent* keyEvent = factory->createKeyEvent(); KeyEvent* keyEvent = factory->createKeyEvent();
if (!keyEvent) return NO_MEMORY; if (!keyEvent) return NO_MEMORY;
initializeKeyEvent(keyEvent, &msg); initializeKeyEvent(keyEvent, &mMsg);
*outSeq = msg.body.key.seq; *outSeq = mMsg.body.key.seq;
*outEvent = keyEvent; *outEvent = keyEvent;
#if DEBUG_TRANSPORT_ACTIONS #if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed key event, seq=%u", ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
@@ -408,10 +397,10 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
} }
case AINPUT_EVENT_TYPE_MOTION: { case AINPUT_EVENT_TYPE_MOTION: {
ssize_t batchIndex = findBatch(msg.body.motion.deviceId, msg.body.motion.source); ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
if (batchIndex >= 0) { if (batchIndex >= 0) {
Batch& batch = mBatches.editItemAt(batchIndex); Batch& batch = mBatches.editItemAt(batchIndex);
if (canAppendSamples(&batch.event, &msg)) { if (canAppendSamples(&batch.event, &mMsg)) {
// Send finished message for the earlier part of the batch. // Send finished message for the earlier part of the batch.
// Claim that we handled the event. (The dispatcher doesn't care either // Claim that we handled the event. (The dispatcher doesn't care either
// way at the moment.) // way at the moment.)
@@ -421,8 +410,8 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
} }
// Append to the batch and save the new sequence number for the tail end. // Append to the batch and save the new sequence number for the tail end.
appendSamples(&batch.event, &msg); appendSamples(&batch.event, &mMsg);
batch.seq = msg.body.motion.seq; batch.seq = mMsg.body.motion.seq;
#if DEBUG_TRANSPORT_ACTIONS #if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ appended to batch event", ALOGD("channel '%s' consumer ~ appended to batch event",
mChannel->getName().string()); mChannel->getName().string());
@@ -433,9 +422,8 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
if (! motionEvent) return NO_MEMORY; if (! motionEvent) return NO_MEMORY;
// We cannot append to the batch in progress, so we need to consume // We cannot append to the batch in progress, so we need to consume
// the previous batch right now and defer the new event until later. // the previous batch right now and defer the new message until later.
mDeferredEventSeq = msg.body.motion.seq; mMsgDeferred = true;
initializeMotionEvent(&mDeferredEvent, &msg);
// Return the end of the previous batch. // Return the end of the previous batch.
motionEvent->copyFrom(&batch.event, true /*keepHistory*/); motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
@@ -452,12 +440,12 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
} }
// Start a new batch if needed. // Start a new batch if needed.
if (msg.body.motion.action == AMOTION_EVENT_ACTION_MOVE if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
|| msg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) { || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
mBatches.push(); mBatches.push();
Batch& batch = mBatches.editTop(); Batch& batch = mBatches.editTop();
batch.seq = msg.body.motion.seq; batch.seq = mMsg.body.motion.seq;
initializeMotionEvent(&batch.event, &msg); initializeMotionEvent(&batch.event, &mMsg);
#if DEBUG_TRANSPORT_ACTIONS #if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ started batch event", ALOGD("channel '%s' consumer ~ started batch event",
mChannel->getName().string()); mChannel->getName().string());
@@ -468,8 +456,8 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
MotionEvent* motionEvent = factory->createMotionEvent(); MotionEvent* motionEvent = factory->createMotionEvent();
if (! motionEvent) return NO_MEMORY; if (! motionEvent) return NO_MEMORY;
initializeMotionEvent(motionEvent, &msg); initializeMotionEvent(motionEvent, &mMsg);
*outSeq = msg.body.motion.seq; *outSeq = mMsg.body.motion.seq;
*outEvent = motionEvent; *outEvent = motionEvent;
#if DEBUG_TRANSPORT_ACTIONS #if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u", ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
@@ -480,7 +468,7 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
default: default:
ALOGE("channel '%s' consumer ~ Received unexpected message of type %d", ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
mChannel->getName().string(), msg.header.type); mChannel->getName().string(), mMsg.header.type);
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
} }