Merge "Refactor how timeouts are calculated. (DO NOT MERGE)" into honeycomb-mr2
This commit is contained in:
@ -88,6 +88,16 @@ nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
|
||||
nsecs_t systemTime(int clock);
|
||||
#endif // def __cplusplus
|
||||
|
||||
/**
|
||||
* Returns the number of milliseconds to wait between the reference time and the timeout time.
|
||||
* If the timeout is in the past relative to the reference time, returns 0.
|
||||
* If the timeout is more than INT_MAX milliseconds in the future relative to the reference time,
|
||||
* such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay.
|
||||
* Otherwise, returns the difference between the reference time and timeout time
|
||||
* rounded up to the next millisecond.
|
||||
*/
|
||||
int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -218,14 +218,10 @@ int Looper::pollInner(int timeoutMillis) {
|
||||
// Adjust the timeout based on when the next message is due.
|
||||
if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
|
||||
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
if (mNextMessageUptime <= now) {
|
||||
timeoutMillis = 0;
|
||||
} else {
|
||||
uint64_t delay = (mNextMessageUptime - now + 999999LL) / 1000000LL;
|
||||
if (delay < INT_MAX
|
||||
&& (timeoutMillis < 0 || int(delay) < timeoutMillis)) {
|
||||
timeoutMillis = int(delay);
|
||||
}
|
||||
int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
|
||||
if (messageTimeoutMillis >= 0
|
||||
&& (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
|
||||
timeoutMillis = messageTimeoutMillis;
|
||||
}
|
||||
#if DEBUG_POLL_AND_WAKE
|
||||
LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
|
||||
@ -444,12 +440,11 @@ int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outDat
|
||||
return result;
|
||||
}
|
||||
|
||||
nsecs_t timeoutNanos = endTime - systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
if (timeoutNanos <= 0) {
|
||||
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
|
||||
if (timeoutMillis == 0) {
|
||||
return ALOOPER_POLL_TIMEOUT;
|
||||
}
|
||||
|
||||
timeoutMillis = int(nanoseconds_to_milliseconds(timeoutNanos + 999999LL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_WIN32_THREADS
|
||||
#include <windows.h>
|
||||
@ -53,6 +54,23 @@ nsecs_t systemTime(int clock)
|
||||
#endif
|
||||
}
|
||||
|
||||
int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)
|
||||
{
|
||||
int timeoutDelayMillis;
|
||||
if (timeoutTime > referenceTime) {
|
||||
uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime);
|
||||
if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) {
|
||||
timeoutDelayMillis = -1;
|
||||
} else {
|
||||
timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL;
|
||||
}
|
||||
} else {
|
||||
timeoutDelayMillis = 0;
|
||||
}
|
||||
return timeoutDelayMillis;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
* DurationTimer
|
||||
|
@ -445,7 +445,7 @@ EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool EventHub::getEvent(RawEvent* outEvent) {
|
||||
bool EventHub::getEvent(int timeoutMillis, RawEvent* outEvent) {
|
||||
outEvent->deviceId = 0;
|
||||
outEvent->type = 0;
|
||||
outEvent->scanCode = 0;
|
||||
@ -598,13 +598,20 @@ bool EventHub::getEvent(RawEvent* outEvent) {
|
||||
// when this happens, the EventHub holds onto its own user wake lock while the client
|
||||
// is processing events. Thus the system can only sleep if there are no events
|
||||
// pending or currently being processed.
|
||||
//
|
||||
// The timeout is advisory only. If the device is asleep, it will not wake just to
|
||||
// service the timeout.
|
||||
release_wake_lock(WAKE_LOCK_ID);
|
||||
|
||||
int pollResult = poll(mFds.editArray(), mFds.size(), -1);
|
||||
int pollResult = poll(mFds.editArray(), mFds.size(), timeoutMillis);
|
||||
|
||||
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
|
||||
|
||||
if (pollResult <= 0) {
|
||||
if (pollResult == 0) {
|
||||
// Timed out.
|
||||
return false;
|
||||
}
|
||||
if (pollResult < 0) {
|
||||
if (errno != EINTR) {
|
||||
LOGW("poll failed (errno=%d)\n", errno);
|
||||
usleep(100000);
|
||||
|
@ -186,8 +186,13 @@ public:
|
||||
* This ensures that the device will not go to sleep while the event is being processed.
|
||||
* If the device needs to remain awake longer than that, then the caller is responsible
|
||||
* for taking care of it (say, by poking the power manager user activity timer).
|
||||
*
|
||||
* The timeout is advisory only. If the device is asleep, it will not wake just to
|
||||
* service the timeout.
|
||||
*
|
||||
* Returns true if an event was obtained, false if the timeout expired.
|
||||
*/
|
||||
virtual bool getEvent(RawEvent* outEvent) = 0;
|
||||
virtual bool getEvent(int timeoutMillis, RawEvent* outEvent) = 0;
|
||||
|
||||
/*
|
||||
* Query current input state.
|
||||
@ -244,7 +249,7 @@ public:
|
||||
virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags) const;
|
||||
|
||||
virtual bool getEvent(RawEvent* outEvent);
|
||||
virtual bool getEvent(int timeoutMillis, RawEvent* outEvent);
|
||||
|
||||
virtual bool hasLed(int32_t deviceId, int32_t led) const;
|
||||
virtual void setLedState(int32_t deviceId, int32_t led, bool on);
|
||||
|
@ -246,15 +246,7 @@ void InputDispatcher::dispatchOnce() {
|
||||
|
||||
// Wait for callback or timeout or wake. (make sure we round up, not down)
|
||||
nsecs_t currentTime = now();
|
||||
int32_t timeoutMillis;
|
||||
if (nextWakeupTime > currentTime) {
|
||||
uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
|
||||
timeout = (timeout + 999999LL) / 1000000LL;
|
||||
timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
|
||||
} else {
|
||||
timeoutMillis = 0;
|
||||
}
|
||||
|
||||
int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
|
||||
mLooper->pollOnce(timeoutMillis);
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub,
|
||||
const sp<InputReaderPolicyInterface>& policy,
|
||||
const sp<InputDispatcherInterface>& dispatcher) :
|
||||
mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
|
||||
mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
|
||||
mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX) {
|
||||
configureExcludedDevices();
|
||||
updateGlobalMetaState();
|
||||
updateInputConfiguration();
|
||||
@ -244,16 +244,28 @@ InputReader::~InputReader() {
|
||||
}
|
||||
|
||||
void InputReader::loopOnce() {
|
||||
int32_t timeoutMillis = -1;
|
||||
if (mNextTimeout != LLONG_MAX) {
|
||||
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
|
||||
}
|
||||
|
||||
RawEvent rawEvent;
|
||||
mEventHub->getEvent(& rawEvent);
|
||||
|
||||
if (mEventHub->getEvent(timeoutMillis, &rawEvent)) {
|
||||
#if DEBUG_RAW_EVENTS
|
||||
LOGD("Input event: device=%d type=0x%04x scancode=0x%04x keycode=0x%04x value=0x%04x",
|
||||
rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
|
||||
rawEvent.value);
|
||||
LOGD("Input event: device=%d type=0x%04x scancode=0x%04x keycode=0x%04x value=0x%04x",
|
||||
rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
|
||||
rawEvent.value);
|
||||
#endif
|
||||
|
||||
process(& rawEvent);
|
||||
process(&rawEvent);
|
||||
} else {
|
||||
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
#if DEBUG_RAW_EVENTS
|
||||
LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
|
||||
#endif
|
||||
mNextTimeout = LLONG_MAX;
|
||||
timeoutExpired(now);
|
||||
}
|
||||
}
|
||||
|
||||
void InputReader::process(const RawEvent* rawEvent) {
|
||||
@ -415,6 +427,19 @@ void InputReader::consumeEvent(const RawEvent* rawEvent) {
|
||||
} // release device registry reader lock
|
||||
}
|
||||
|
||||
void InputReader::timeoutExpired(nsecs_t when) {
|
||||
{ // acquire device registry reader lock
|
||||
RWLock::AutoRLock _rl(mDeviceRegistryLock);
|
||||
|
||||
for (size_t i = 0; i < mDevices.size(); i++) {
|
||||
InputDevice* device = mDevices.valueAt(i);
|
||||
if (!device->isIgnored()) {
|
||||
device->timeoutExpired(when);
|
||||
}
|
||||
}
|
||||
} // release device registry reader lock
|
||||
}
|
||||
|
||||
void InputReader::handleConfigurationChanged(nsecs_t when) {
|
||||
// Reset global meta state because it depends on the list of all configured devices.
|
||||
updateGlobalMetaState();
|
||||
@ -525,6 +550,12 @@ void InputReader::fadePointer() {
|
||||
} // release device registry reader lock
|
||||
}
|
||||
|
||||
void InputReader::requestTimeoutAtTime(nsecs_t when) {
|
||||
if (when < mNextTimeout) {
|
||||
mNextTimeout = when;
|
||||
}
|
||||
}
|
||||
|
||||
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
|
||||
{ // acquire state lock
|
||||
AutoMutex _l(mStateLock);
|
||||
@ -762,6 +793,14 @@ void InputDevice::process(const RawEvent* rawEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
void InputDevice::timeoutExpired(nsecs_t when) {
|
||||
size_t numMappers = mMappers.size();
|
||||
for (size_t i = 0; i < numMappers; i++) {
|
||||
InputMapper* mapper = mMappers[i];
|
||||
mapper->timeoutExpired(when);
|
||||
}
|
||||
}
|
||||
|
||||
void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
|
||||
outDeviceInfo->initialize(mId, mName);
|
||||
|
||||
@ -853,6 +892,9 @@ void InputMapper::configure() {
|
||||
void InputMapper::reset() {
|
||||
}
|
||||
|
||||
void InputMapper::timeoutExpired(nsecs_t when) {
|
||||
}
|
||||
|
||||
int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
|
||||
return AKEY_STATE_UNKNOWN;
|
||||
}
|
||||
@ -2556,6 +2598,19 @@ void TouchInputMapper::reset() {
|
||||
}
|
||||
|
||||
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
|
||||
#if DEBUG_RAW_EVENTS
|
||||
if (!havePointerIds) {
|
||||
LOGD("syncTouch: pointerCount=%d, no pointer ids", mCurrentTouch.pointerCount);
|
||||
} else {
|
||||
LOGD("syncTouch: pointerCount=%d, up=0x%08x, down=0x%08x, move=0x%08x, "
|
||||
"last=0x%08x, current=0x%08x", mCurrentTouch.pointerCount,
|
||||
mLastTouch.idBits.value & ~mCurrentTouch.idBits.value,
|
||||
mCurrentTouch.idBits.value & ~mLastTouch.idBits.value,
|
||||
mLastTouch.idBits.value & mCurrentTouch.idBits.value,
|
||||
mLastTouch.idBits.value, mCurrentTouch.idBits.value);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Preprocess pointer data.
|
||||
if (mParameters.useBadTouchFilter) {
|
||||
if (applyBadTouchFilter()) {
|
||||
@ -2569,7 +2624,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! havePointerIds) {
|
||||
if (!havePointerIds) {
|
||||
calculatePointerIds();
|
||||
}
|
||||
|
||||
|
@ -159,6 +159,8 @@ public:
|
||||
|
||||
virtual void fadePointer() = 0;
|
||||
|
||||
virtual void requestTimeoutAtTime(nsecs_t when) = 0;
|
||||
|
||||
virtual InputReaderPolicyInterface* getPolicy() = 0;
|
||||
virtual InputDispatcherInterface* getDispatcher() = 0;
|
||||
virtual EventHubInterface* getEventHub() = 0;
|
||||
@ -233,6 +235,7 @@ private:
|
||||
void configureExcludedDevices();
|
||||
|
||||
void consumeEvent(const RawEvent* rawEvent);
|
||||
void timeoutExpired(nsecs_t when);
|
||||
|
||||
void handleConfigurationChanged(nsecs_t when);
|
||||
|
||||
@ -253,6 +256,9 @@ private:
|
||||
virtual bool shouldDropVirtualKey(nsecs_t now,
|
||||
InputDevice* device, int32_t keyCode, int32_t scanCode);
|
||||
|
||||
nsecs_t mNextTimeout;
|
||||
virtual void requestTimeoutAtTime(nsecs_t when);
|
||||
|
||||
// state queries
|
||||
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
|
||||
int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
|
||||
@ -296,6 +302,7 @@ public:
|
||||
void configure();
|
||||
void reset();
|
||||
void process(const RawEvent* rawEvent);
|
||||
void timeoutExpired(nsecs_t when);
|
||||
|
||||
void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
|
||||
int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
|
||||
@ -352,6 +359,7 @@ public:
|
||||
virtual void configure();
|
||||
virtual void reset();
|
||||
virtual void process(const RawEvent* rawEvent) = 0;
|
||||
virtual void timeoutExpired(nsecs_t when);
|
||||
|
||||
virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
|
||||
virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
|
||||
|
@ -622,7 +622,7 @@ private:
|
||||
mExcludedDevices.add(String8(deviceName));
|
||||
}
|
||||
|
||||
virtual bool getEvent(RawEvent* outEvent) {
|
||||
virtual bool getEvent(int timeoutMillis, RawEvent* outEvent) {
|
||||
if (mEvents.empty()) {
|
||||
return false;
|
||||
}
|
||||
@ -780,6 +780,9 @@ private:
|
||||
|
||||
virtual void fadePointer() {
|
||||
}
|
||||
|
||||
virtual void requestTimeoutAtTime(nsecs_t when) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user