Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 414e1784 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add thread safety annotations to inputflinger"

parents 3d76d5d7 61291d41
Loading
Loading
Loading
Loading
+20 −36
Original line number Diff line number Diff line
@@ -12,8 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.

cc_defaults {
    name: "inputflinger_defaults",
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
        "-Wthread-safety",
    ],
}

cc_library_shared {
    name: "libinputflinger",
    defaults: ["inputflinger_defaults"],

    srcs: [
        "InputClassifier.cpp",
@@ -23,10 +35,10 @@ cc_library_shared {

    shared_libs: [
        "android.hardware.input.classifier@1.0",
        "libbase",
        "libinputflinger_base",
        "libinputreporter",
        "libinputreader",
        "libbase",
        "libbinder",
        "libcutils",
        "libhidlbase",
@@ -38,12 +50,6 @@ cc_library_shared {
    ],

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
        // TODO(b/123097103): annotate InputDispatcher and uncomment the following line
        //"-Wthread-safety",
        // TODO(b/23084678): Move inputflinger to its own process and mark it hidden
        //-fvisibility=hidden
    ],
@@ -55,15 +61,14 @@ cc_library_shared {

}


cc_library_headers {
    name: "libinputflinger_headers",

    export_include_dirs: ["include"],
}

cc_library_shared {
    name: "libinputreader",
    defaults: ["inputflinger_defaults"],

    srcs: [
        "EventHub.cpp",
@@ -73,17 +78,16 @@ cc_library_shared {
    ],

    shared_libs: [
        "libinputflinger_base",
        "libbase",
        "libinputflinger_base",
        "libcrypto",
        "libcutils",
        "libinput",
        "liblog",
        "libutils",
        "libui",
        "libutils",
        "libhardware_legacy",
        "libstatslog",
        "libutils",
    ],

    header_libs: [
@@ -93,17 +97,11 @@ cc_library_shared {
    export_header_lib_headers: [
        "libinputflinger_headers",
    ],

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
    ],
}

cc_library_shared {
    name: "libinputflinger_base",
    defaults: ["inputflinger_defaults"],

    srcs: [
        "InputListener.cpp",
@@ -124,24 +122,17 @@ cc_library_shared {
    export_header_lib_headers: [
        "libinputflinger_headers",
    ],

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
    ],
}

cc_library_shared {
    name: "libinputreporter",
    defaults: ["inputflinger_defaults"],

    srcs: [
        "InputReporter.cpp",
    ],

    shared_libs: [
        "libbase",
        "liblog",
        "libutils",
    ],
@@ -153,13 +144,6 @@ cc_library_shared {
    export_header_lib_headers: [
        "libinputflinger_headers",
    ],

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
    ],
}

subdirs = [
+16 −9
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef _UI_INPUT_BLOCKING_QUEUE_H
#define _UI_INPUT_BLOCKING_QUEUE_H

#include "android-base/thread_annotations.h"
#include <condition_variable>
#include <mutex>
#include <vector>
@@ -43,10 +44,14 @@ public:
     */
    T pop() {
        std::unique_lock<std::mutex> lock(mLock);
        mHasElements.wait(lock, [this]{ return !this->mQueue.empty(); });
        android::base::ScopedLockAssertion assumeLock(mLock);
        mHasElements.wait(lock, [this]{
                android::base::ScopedLockAssertion assumeLock(mLock);
                return !this->mQueue.empty();
        });
        T t = std::move(mQueue.front());
        mQueue.erase(mQueue.begin());
        return std::move(t);
        return t;
    };

    /**
@@ -56,17 +61,19 @@ public:
     * Return false if the queue is full.
     */
    bool push(T&& t) {
        std::unique_lock<std::mutex> lock(mLock);
        {
            std::scoped_lock lock(mLock);
            if (mQueue.size() == mCapacity) {
                return false;
            }
            mQueue.push_back(std::move(t));
        }
        mHasElements.notify_one();
        return true;
    };

    void erase(const std::function<bool(const T&)>& lambda) {
        std::unique_lock<std::mutex> lock(mLock);
        std::scoped_lock lock(mLock);
        mQueue.erase(std::remove_if(mQueue.begin(), mQueue.end(),
                [&lambda](const T& t) { return lambda(t); }), mQueue.end());
    }
@@ -91,7 +98,7 @@ public:
    }

private:
    size_t mCapacity;
    const size_t mCapacity;
    /**
     * Used to signal that mQueue is non-empty.
     */
@@ -100,7 +107,7 @@ private:
     * Lock for accessing and waiting on elements.
     */
    std::mutex mLock;
    std::vector<T> mQueue; //GUARDED_BY(mLock)
    std::vector<T> mQueue GUARDED_BY(mLock);
};


+5 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef _UI_INPUT_CLASSIFIER_H
#define _UI_INPUT_CLASSIFIER_H

#include <android-base/thread_annotations.h>
#include <utils/RefBase.h>
#include <unordered_map>
#include <thread>
@@ -151,7 +152,7 @@ private:
     * getClassification / setClassification methods.
     */
    std::unordered_map<int32_t /*deviceId*/, MotionClassification>
            mClassifications; //GUARDED_BY(mLock);
            mClassifications GUARDED_BY(mLock);
    /**
     * Set the current classification for a given device.
     */
@@ -172,8 +173,8 @@ private:
     *
     * Accessed indirectly by both InputClassifier thread and the thread that receives notifyMotion.
     */
    std::unordered_map<int32_t /*deviceId*/, nsecs_t /*downTime*/>
            mLastDownTimes; //GUARDED_BY(mLock);
    std::unordered_map<int32_t /*deviceId*/, nsecs_t /*downTime*/> mLastDownTimes GUARDED_BY(mLock);

    void updateLastDownTime(int32_t deviceId, nsecs_t downTime);

    /**
+38 −41
Original line number Diff line number Diff line
@@ -401,7 +401,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    case EventEntry::TYPE_KEY: {
        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
        if (isAppSwitchDue) {
            if (isAppSwitchKeyEventLocked(typedEntry)) {
            if (isAppSwitchKeyEvent(typedEntry)) {
                resetPendingAppSwitchLocked(true);
                isAppSwitchDue = false;
            } else if (dropReason == DROP_REASON_NOT_DROPPED) {
@@ -409,7 +409,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
            }
        }
        if (dropReason == DROP_REASON_NOT_DROPPED
                && isStaleEventLocked(currentTime, typedEntry)) {
                && isStaleEvent(currentTime, typedEntry)) {
            dropReason = DROP_REASON_STALE;
        }
        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
@@ -425,7 +425,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
            dropReason = DROP_REASON_APP_SWITCH;
        }
        if (dropReason == DROP_REASON_NOT_DROPPED
                && isStaleEventLocked(currentTime, typedEntry)) {
                && isStaleEvent(currentTime, typedEntry)) {
            dropReason = DROP_REASON_STALE;
        }
        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
@@ -463,7 +463,7 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
        // If the application takes too long to catch up then we drop all events preceding
        // the app switch key.
        KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
        if (isAppSwitchKeyEventLocked(keyEntry)) {
        if (isAppSwitchKeyEvent(keyEntry)) {
            if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
                mAppSwitchSawKeyDown = true;
            } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
@@ -615,13 +615,13 @@ void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropR
    }
}

bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
static bool isAppSwitchKeyCode(int32_t keyCode) {
    return keyCode == AKEYCODE_HOME
            || keyCode == AKEYCODE_ENDCALL
            || keyCode == AKEYCODE_APP_SWITCH;
}

bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
    return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
            && isAppSwitchKeyCode(keyEntry->keyCode)
            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
@@ -644,7 +644,7 @@ void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
#endif
}

bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
    return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
}

@@ -756,7 +756,7 @@ bool InputDispatcher::dispatchConfigurationChangedLocked(

    // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
    CommandEntry* commandEntry = postCommandLocked(
            & InputDispatcher::doNotifyConfigurationChangedInterruptible);
            & InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
    commandEntry->eventTime = entry->eventTime;
    return true;
}
@@ -811,7 +811,7 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,

        entry->dispatchInProgress = true;

        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
        logOutboundKeyDetails("dispatchKey - ", entry);
    }

    // Handle case where the policy asked us to try again later last time.
@@ -878,7 +878,7 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
    return true;
}

void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
#if DEBUG_OUTBOUND_EVENT_DETAILS
    ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
            "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
@@ -896,7 +896,7 @@ bool InputDispatcher::dispatchMotionLocked(
    if (! entry->dispatchInProgress) {
        entry->dispatchInProgress = true;

        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
        logOutboundMotionDetails("dispatchMotion - ", entry);
    }

    // Clean up if dropping the event.
@@ -968,7 +968,7 @@ bool InputDispatcher::dispatchMotionLocked(
}


void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
#if DEBUG_OUTBOUND_EVENT_DETAILS
    ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
            ", policyFlags=0x%x, "
@@ -1049,7 +1049,7 @@ int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
#if DEBUG_FOCUS
            ALOGD("Waiting for application to become ready for input: %s.  Reason: %s",
                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str(),
                    getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
                    reason);
#endif
            nsecs_t timeout;
@@ -1233,8 +1233,7 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Failed:
Unresponsive:
    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
    updateDispatchStatisticsLocked(currentTime, entry,
            injectionResult, timeSpentWaitingForApplication);
    updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
#if DEBUG_FOCUS
    ALOGD("findFocusedWindow finished: injectionResult=%d, "
            "timeSpentWaitingForApplication=%0.1fms",
@@ -1654,8 +1653,7 @@ Unresponsive:
    mTempTouchState.reset();

    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
    updateDispatchStatisticsLocked(currentTime, entry,
            injectionResult, timeSpentWaitingForApplication);
    updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
#if DEBUG_FOCUS
    ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
            "timeSpentWaitingForApplication=%0.1fms",
@@ -1857,7 +1855,7 @@ std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentT
    return "";
}

std::string InputDispatcher::getApplicationWindowLabelLocked(
std::string InputDispatcher::getApplicationWindowLabel(
        const sp<InputApplicationHandle>& applicationHandle,
        const sp<InputWindowHandle>& windowHandle) {
    if (applicationHandle != nullptr) {
@@ -1956,7 +1954,7 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
#if DEBUG_FOCUS
            ALOGD("channel '%s' ~ Split motion event.",
                    connection->getInputChannelName().c_str());
            logOutboundMotionDetailsLocked("  ", splitMotionEntry);
            logOutboundMotionDetails("  ", splitMotionEntry);
#endif
            enqueueDispatchEntriesLocked(currentTime, connection,
                    splitMotionEntry, inputTarget);
@@ -2076,12 +2074,12 @@ void InputDispatcher::enqueueDispatchEntryLocked(

    // Remember that we are waiting for this dispatch to complete.
    if (dispatchEntry->hasForegroundTarget()) {
        incrementPendingForegroundDispatchesLocked(eventEntry);
        incrementPendingForegroundDispatches(eventEntry);
    }

    // Enqueue the dispatch entry.
    connection->outboundQueue.enqueueAtTail(dispatchEntry);
    traceOutboundQueueLengthLocked(connection);
    traceOutboundQueueLength(connection);
}

void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
@@ -2196,9 +2194,9 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,

        // Re-enqueue the event on the wait queue.
        connection->outboundQueue.dequeue(dispatchEntry);
        traceOutboundQueueLengthLocked(connection);
        traceOutboundQueueLength(connection);
        connection->waitQueue.enqueueAtTail(dispatchEntry);
        traceWaitQueueLengthLocked(connection);
        traceWaitQueueLength(connection);
    }
}

@@ -2229,9 +2227,9 @@ void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,

    // Clear the dispatch queues.
    drainDispatchQueueLocked(&connection->outboundQueue);
    traceOutboundQueueLengthLocked(connection);
    traceOutboundQueueLength(connection);
    drainDispatchQueueLocked(&connection->waitQueue);
    traceWaitQueueLengthLocked(connection);
    traceWaitQueueLength(connection);

    // The connection appears to be unrecoverably broken.
    // Ignore already broken or zombie connections.
@@ -2374,11 +2372,11 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
            EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
            switch (cancelationEventEntry->type) {
            case EventEntry::TYPE_KEY:
                logOutboundKeyDetailsLocked("cancel - ",
                logOutboundKeyDetails("cancel - ",
                        static_cast<KeyEntry*>(cancelationEventEntry));
                break;
            case EventEntry::TYPE_MOTION:
                logOutboundMotionDetailsLocked("cancel - ",
                logOutboundMotionDetails("cancel - ",
                        static_cast<MotionEntry*>(cancelationEventEntry));
                break;
            }
@@ -2994,7 +2992,7 @@ void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t inject
    }
}

void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
    InjectionState* injectionState = entry->injectionState;
    if (injectionState) {
        injectionState->pendingForegroundDispatches += 1;
@@ -3038,8 +3036,7 @@ sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
    return nullptr;
}

bool InputDispatcher::hasWindowHandleLocked(
        const sp<InputWindowHandle>& windowHandle) const {
bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
    for (auto& it : mWindowHandlesByDisplay) {
        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
        size_t numWindows = windowHandles.size();
@@ -3884,7 +3881,7 @@ void InputDispatcher::onANRLocked(
    float waitDuration = (currentTime - waitStartTime) * 0.000001f;
    ALOGI("Application is not responding: %s.  "
            "It has been %0.1fms since event, %0.1fms since wait started.  Reason: %s",
            getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str(),
            getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
            dispatchLatency, waitDuration, reason);

    // Capture a record of the InputDispatcher state at the time of the ANR.
@@ -3897,7 +3894,7 @@ void InputDispatcher::onANRLocked(
    mLastANRState += INDENT "ANR:\n";
    mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
    mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
            getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str());
            getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
    mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
    mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
    mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
@@ -3911,7 +3908,7 @@ void InputDispatcher::onANRLocked(
    commandEntry->reason = reason;
}

void InputDispatcher::doNotifyConfigurationChangedInterruptible(
void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible (
        CommandEntry* commandEntry) {
    mLock.unlock();

@@ -4027,10 +4024,10 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
        // a few things.
        if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
            connection->waitQueue.dequeue(dispatchEntry);
            traceWaitQueueLengthLocked(connection);
            traceWaitQueueLength(connection);
            if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
                connection->outboundQueue.enqueueAtHead(dispatchEntry);
                traceOutboundQueueLengthLocked(connection);
                traceOutboundQueueLength(connection);
            } else {
                releaseDispatchEntryLocked(dispatchEntry);
            }
@@ -4242,7 +4239,7 @@ void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry)
            entry->downTime, entry->eventTime);
}

void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
        int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
    // TODO Write some statistics about how long we spend waiting.
}
@@ -4253,7 +4250,7 @@ void InputDispatcher::traceInboundQueueLengthLocked() {
    }
}

void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
    if (ATRACE_ENABLED()) {
        char counterName[40];
        snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
@@ -4261,7 +4258,7 @@ void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& conne
    }
}

void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
    if (ATRACE_ENABLED()) {
        char counterName[40];
        snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
+118 −110

File changed.

Preview size limit exceeded, changes collapsed.