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

Commit 61291d41 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Add thread safety annotations to inputflinger

Enable -Wthread-safety for services/inputflinger code.

Test: compile-time
Bug: 123097103
Change-Id: I2977434a5ff243dc256ae0132966293209cb818a
parent c1072d30
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.