summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/gui/SensorEventQueue.cpp18
-rw-r--r--libs/ui/InputDispatcher.cpp123
-rw-r--r--libs/ui/InputTransport.cpp11
-rw-r--r--libs/utils/Looper.cpp14
4 files changed, 110 insertions, 56 deletions
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index c3a9f22..f935524 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -70,9 +70,13 @@ ssize_t SensorEventQueue::write(ASensorEvent const* events, size_t numEvents)
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents)
{
ssize_t size = mSensorChannel->read(events, numEvents*sizeof(events[0]));
+ LOGE_IF(size<0 && size!=-EAGAIN,
+ "SensorChannel::read error (%s)", strerror(-size));
if (size >= 0) {
if (size % sizeof(events[0])) {
// partial read!!! should never happen.
+ LOGE("SensorEventQueue partial read (event-size=%u, read=%d)",
+ sizeof(events[0]), int(size));
return -EINVAL;
}
// returns number of events read
@@ -95,8 +99,18 @@ status_t SensorEventQueue::waitForEvent() const
{
const int fd = getFd();
sp<Looper> looper(getLooper());
- int32_t result = looper->pollOnce(-1);
- return (result == fd) ? status_t(NO_ERROR) : status_t(-1);
+
+ int32_t result;
+ do {
+ result = looper->pollOnce(-1);
+ if (result == ALOOPER_EVENT_ERROR) {
+ LOGE("SensorChannel::waitForEvent error (errno=%d)", errno);
+ result = -EPIPE; // unknown error, so we make up one
+ break;
+ }
+ } while (result != fd);
+
+ return (result == fd) ? status_t(NO_ERROR) : result;
}
status_t SensorEventQueue::wake() const
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 6713817..1cf7592 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -122,7 +122,7 @@ InputDispatcher::~InputDispatcher() {
AutoMutex _l(mLock);
resetKeyRepeatLocked();
- releasePendingEventLocked(true);
+ releasePendingEventLocked();
drainInboundQueueLocked();
}
@@ -174,7 +174,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
if (! mDispatchEnabled) {
if (mPendingEvent || ! mInboundQueue.isEmpty()) {
LOGI("Dropping pending events because input dispatch is disabled.");
- releasePendingEventLocked(true);
+ releasePendingEventLocked();
drainInboundQueueLocked();
}
return;
@@ -281,51 +281,50 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
// Now we have an event to dispatch.
assert(mPendingEvent != NULL);
- bool wasDispatched = false;
- bool wasDropped = false;
+ bool done = false;
switch (mPendingEvent->type) {
case EventEntry::TYPE_CONFIGURATION_CHANGED: {
ConfigurationChangedEntry* typedEntry =
static_cast<ConfigurationChangedEntry*>(mPendingEvent);
- wasDispatched = dispatchConfigurationChangedLocked(currentTime, typedEntry);
+ done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
break;
}
case EventEntry::TYPE_KEY: {
KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
- if (isAppSwitchPendingLocked()) {
- if (isAppSwitchKey(typedEntry->keyCode)) {
+ bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
+ bool dropEvent = isAppSwitchDue && ! appSwitchKey;
+ done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
+ nextWakeupTime);
+ if (done) {
+ if (dropEvent) {
+ LOGI("Dropped key because of pending overdue app switch.");
+ } else if (appSwitchKey) {
resetPendingAppSwitchLocked(true);
- } else if (isAppSwitchDue) {
- LOGI("Dropping key because of pending overdue app switch.");
- wasDropped = true;
- break;
}
}
- wasDispatched = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
- nextWakeupTime);
break;
}
case EventEntry::TYPE_MOTION: {
MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
- if (isAppSwitchDue) {
- LOGI("Dropping motion because of pending overdue app switch.");
- wasDropped = true;
- break;
+ bool dropEvent = isAppSwitchDue;
+ done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
+ if (done) {
+ if (dropEvent) {
+ LOGI("Dropped motion because of pending overdue app switch.");
+ }
}
- wasDispatched = dispatchMotionLocked(currentTime, typedEntry, nextWakeupTime);
break;
}
default:
assert(false);
- wasDropped = true;
break;
}
- if (wasDispatched || wasDropped) {
- releasePendingEventLocked(wasDropped);
+ if (done) {
+ releasePendingEventLocked();
*nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
}
}
@@ -403,21 +402,21 @@ InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command comman
void InputDispatcher::drainInboundQueueLocked() {
while (! mInboundQueue.isEmpty()) {
EventEntry* entry = mInboundQueue.dequeueAtHead();
- releaseInboundEventLocked(entry, true /*wasDropped*/);
+ releaseInboundEventLocked(entry);
}
}
-void InputDispatcher::releasePendingEventLocked(bool wasDropped) {
+void InputDispatcher::releasePendingEventLocked() {
if (mPendingEvent) {
- releaseInboundEventLocked(mPendingEvent, wasDropped);
+ releaseInboundEventLocked(mPendingEvent);
mPendingEvent = NULL;
}
}
-void InputDispatcher::releaseInboundEventLocked(EventEntry* entry, bool wasDropped) {
- if (wasDropped) {
+void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
+ if (entry->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
#if DEBUG_DISPATCH_CYCLE
- LOGD("Pending event was dropped.");
+ LOGD("Inbound event was dropped. Setting injection result to failed.");
#endif
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
}
@@ -492,7 +491,41 @@ bool InputDispatcher::dispatchConfigurationChangedLocked(
bool InputDispatcher::dispatchKeyLocked(
nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
- nsecs_t* nextWakeupTime) {
+ bool dropEvent, nsecs_t* nextWakeupTime) {
+ // Give the policy a chance to intercept the key.
+ if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
+ bool trusted;
+ if (! dropEvent && mFocusedWindow) {
+ trusted = checkInjectionPermission(mFocusedWindow,
+ entry->injectorPid, entry->injectorUid);
+ } else {
+ trusted = isEventFromReliableSourceLocked(entry);
+ }
+ if (trusted) {
+ CommandEntry* commandEntry = postCommandLocked(
+ & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
+ if (! dropEvent && mFocusedWindow) {
+ commandEntry->inputChannel = mFocusedWindow->inputChannel;
+ }
+ commandEntry->keyEntry = entry;
+ entry->refCount += 1;
+ return false; // wait for the command to run
+ } else {
+ entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
+ }
+ } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
+ resetTargetsLocked();
+ setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
+ return true;
+ }
+
+ // Clean up if dropping the event.
+ if (dropEvent) {
+ resetTargetsLocked();
+ setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+ return true;
+ }
+
// Preprocessing.
if (! entry->dispatchInProgress) {
logOutboundKeyDetailsLocked("dispatchKey - ", entry);
@@ -521,7 +554,7 @@ bool InputDispatcher::dispatchKeyLocked(
}
entry->dispatchInProgress = true;
- startFindingTargetsLocked(); // resets mCurrentInputTargetsValid
+ resetTargetsLocked();
}
// Identify targets.
@@ -539,20 +572,7 @@ bool InputDispatcher::dispatchKeyLocked(
}
addMonitoringTargetsLocked();
- finishFindingTargetsLocked(window);
- }
-
- // Give the policy a chance to intercept the key.
- if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
- CommandEntry* commandEntry = postCommandLocked(
- & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
- commandEntry->inputChannel = mCurrentInputChannel;
- commandEntry->keyEntry = entry;
- entry->refCount += 1;
- return false; // wait for the command to run
- }
- if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
- return true;
+ commitTargetsLocked(window);
}
// Dispatch the key.
@@ -576,13 +596,20 @@ void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyE
}
bool InputDispatcher::dispatchMotionLocked(
- nsecs_t currentTime, MotionEntry* entry, nsecs_t* nextWakeupTime) {
+ nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
+ // Clean up if dropping the event.
+ if (dropEvent) {
+ resetTargetsLocked();
+ setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+ return true;
+ }
+
// Preprocessing.
if (! entry->dispatchInProgress) {
logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
entry->dispatchInProgress = true;
- startFindingTargetsLocked(); // resets mCurrentInputTargetsValid
+ resetTargetsLocked();
}
bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
@@ -610,7 +637,7 @@ bool InputDispatcher::dispatchMotionLocked(
}
addMonitoringTargetsLocked();
- finishFindingTargetsLocked(window);
+ commitTargetsLocked(window);
}
// Dispatch the motion.
@@ -705,14 +732,14 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi
}
}
-void InputDispatcher::startFindingTargetsLocked() {
+void InputDispatcher::resetTargetsLocked() {
mCurrentInputTargetsValid = false;
mCurrentInputTargets.clear();
mCurrentInputChannel.clear();
mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
}
-void InputDispatcher::finishFindingTargetsLocked(const InputWindow* window) {
+void InputDispatcher::commitTargetsLocked(const InputWindow* window) {
mCurrentInputWindowType = window->layoutParamsType;
mCurrentInputChannel = window->inputChannel;
mCurrentInputTargetsValid = true;
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 4c402dc..2c6346e 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -131,7 +131,10 @@ status_t InputChannel::openInputChannelPair(const String8& name,
}
status_t InputChannel::sendSignal(char signal) {
- ssize_t nWrite = ::write(mSendPipeFd, & signal, 1);
+ ssize_t nWrite;
+ do {
+ nWrite = ::write(mSendPipeFd, & signal, 1);
+ } while (nWrite == -1 && errno == EINTR);
if (nWrite == 1) {
#if DEBUG_CHANNEL_SIGNALS
@@ -147,7 +150,11 @@ status_t InputChannel::sendSignal(char signal) {
}
status_t InputChannel::receiveSignal(char* outSignal) {
- ssize_t nRead = ::read(mReceivePipeFd, outSignal, 1);
+ ssize_t nRead;
+ do {
+ nRead = ::read(mReceivePipeFd, outSignal, 1);
+ } while (nRead == -1 && errno == EINTR);
+
if (nRead == 1) {
#if DEBUG_CHANNEL_SIGNALS
LOGD("channel '%s' ~ received signal '%c'", mName.string(), *outSignal);
diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp
index fd287da..4aa50d6 100644
--- a/libs/utils/Looper.cpp
+++ b/libs/utils/Looper.cpp
@@ -162,9 +162,11 @@ int Looper::pollInner(int timeoutMillis) {
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
if (eventCount < 0) {
- if (errno != EINTR) {
- LOGW("Poll failed with an unexpected error, errno=%d", errno);
+ if (errno == EINTR) {
+ return ALOOPER_POLL_WAKE;
}
+
+ LOGW("Poll failed with an unexpected error, errno=%d", errno);
return ALOOPER_POLL_ERROR;
}
@@ -196,7 +198,7 @@ int Looper::pollInner(int timeoutMillis) {
ssize_t nRead;
do {
nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
- } while (nRead == sizeof(buffer));
+ } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
} else {
LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
}
@@ -272,7 +274,11 @@ void Looper::wake() {
LOGD("%p ~ wake", this);
#endif
- ssize_t nWrite = write(mWakeWritePipeFd, "W", 1);
+ ssize_t nWrite;
+ do {
+ nWrite = write(mWakeWritePipeFd, "W", 1);
+ } while (nWrite == -1 && errno == EINTR);
+
if (nWrite != 1) {
if (errno != EAGAIN) {
LOGW("Could not write wake signal, errno=%d", errno);