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

Commit 0ef096d7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "InputDispatcher: Add InputTracerInterface for tracing input events" into main

parents 08ed729a abcdf5cf
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -164,6 +164,11 @@ std::string KeyEntry::getDescription() const {
                        keyCode, scanCode, metaState, repeatCount, policyFlags);
}

std::ostream& operator<<(std::ostream& out, const KeyEntry& keyEntry) {
    out << keyEntry.getDescription();
    return out;
}

// --- TouchModeEntry ---

TouchModeEntry::TouchModeEntry(int32_t id, nsecs_t eventTime, bool inTouchMode, int displayId)
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include "InjectionState.h"
#include "InputTarget.h"
#include "trace/EventTrackerInterface.h"

#include <gui/InputApplication.h>
#include <input/Input.h>
@@ -125,6 +126,7 @@ struct KeyEntry : EventEntry {
    int32_t scanCode;
    int32_t metaState;
    nsecs_t downTime;
    std::unique_ptr<trace::EventTrackerInterface> traceTracker;

    bool syntheticRepeat; // set to true for synthetic key repeats

@@ -147,6 +149,8 @@ struct KeyEntry : EventEntry {
    std::string getDescription() const override;
};

std::ostream& operator<<(std::ostream& out, const KeyEntry& motionEntry);

struct MotionEntry : EventEntry {
    int32_t deviceId;
    uint32_t source;
@@ -165,6 +169,7 @@ struct MotionEntry : EventEntry {
    nsecs_t downTime;
    std::vector<PointerProperties> pointerProperties;
    std::vector<PointerCoords> pointerCoords;
    std::unique_ptr<trace::EventTrackerInterface> traceTracker;

    size_t getPointerCount() const { return pointerProperties.size(); }

+72 −1
Original line number Diff line number Diff line
@@ -75,6 +75,14 @@ namespace input_flags = com::android::input::flags;
namespace android::inputdispatcher {

namespace {

template <class Entry>
void ensureEventTraced(const Entry& entry) {
    if (!entry.traceTracker) {
        LOG(FATAL) << "Expected event entry to be traced, but it wasn't: " << entry;
    }
}

// Temporarily releases a held mutex for the lifetime of the instance.
// Named to match std::scoped_lock
class scoped_unlock {
@@ -775,6 +783,10 @@ Result<void> validateWindowInfosUpdate(const gui::WindowInfosUpdate& update) {
// --- InputDispatcher ---

InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
      : InputDispatcher(policy, nullptr) {}

InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
                                 std::unique_ptr<trace::InputTracingBackendInterface> traceBackend)
      : mPolicy(policy),
        mPendingEvent(nullptr),
        mLastDropReason(DropReason::NOT_DROPPED),
@@ -797,6 +809,10 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
    SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
#endif
    mKeyRepeatState.lastKeyEntry = nullptr;

    if (traceBackend) {
        // TODO: Create input tracer instance.
    }
}

InputDispatcher::~InputDispatcher() {
@@ -1070,6 +1086,10 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t& nextWakeupTime) {
                dropReason = DropReason::BLOCKED;
            }
            done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
            if (done && mTracer) {
                ensureEventTraced(*keyEntry);
                mTracer->eventProcessingComplete(*keyEntry->traceTracker);
            }
            break;
        }

@@ -1095,6 +1115,10 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t& nextWakeupTime) {
                }
            }
            done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
            if (done && mTracer) {
                ensureEventTraced(*motionEntry);
                mTracer->eventProcessingComplete(*motionEntry->traceTracker);
            }
            break;
        }

@@ -1200,6 +1224,9 @@ bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newE
                                "Unexpected untrusted event.");

            const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
            if (mTracer) {
                ensureEventTraced(keyEntry);
            }

            // If a new up event comes in, and the pending event with same key code has been asked
            // to try again later because of the policy. We have to reset the intercept key wake up
@@ -1221,7 +1248,11 @@ bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newE
        case EventEntry::Type::MOTION: {
            LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
                                "Unexpected untrusted event.");
            if (shouldPruneInboundQueueLocked(static_cast<const MotionEntry&>(entry))) {
            const auto& motionEntry = static_cast<const MotionEntry&>(entry);
            if (mTracer) {
                ensureEventTraced(motionEntry);
            }
            if (shouldPruneInboundQueueLocked(motionEntry)) {
                mNextUnblockedEvent = mInboundQueue.back();
                needWake = true;
            }
@@ -1471,6 +1502,10 @@ std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t cur
                                       entry->repeatCount + 1, entry->downTime);

    newEntry->syntheticRepeat = true;
    if (mTracer) {
        newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
    }

    mKeyRepeatState.lastKeyEntry = newEntry;
    mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
    return newEntry;
@@ -1777,6 +1812,13 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con
    // Add monitor channels from event's or focused display.
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));

    if (mTracer) {
        ensureEventTraced(*entry);
        for (const auto& target : inputTargets) {
            mTracer->dispatchToTargetHint(*entry->traceTracker, target);
        }
    }

    // Dispatch the key.
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
@@ -1902,6 +1944,13 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
    // Add monitor channels from event's or focused display.
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));

    if (mTracer) {
        ensureEventTraced(*entry);
        for (const auto& target : inputTargets) {
            mTracer->dispatchToTargetHint(*entry->traceTracker, target);
        }
    }

    // Dispatch the motion.
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
@@ -3539,6 +3588,7 @@ status_t InputDispatcher::publishMotionEvent(Connection& connection,
    PointerCoords scaledCoords[MAX_POINTERS];
    const PointerCoords* usingCoords = motionEntry.pointerCoords.data();

    // TODO(b/316355518): Do not modify coords before dispatch.
    // Set the X and Y offset and X and Y scale depending on the input source.
    if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
        !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
@@ -3614,6 +3664,9 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                                                  keyEntry.keyCode, keyEntry.scanCode,
                                                  keyEntry.metaState, keyEntry.repeatCount,
                                                  keyEntry.downTime, keyEntry.eventTime);
                if (mTracer) {
                    mTracer->traceEventDispatch(*dispatchEntry, keyEntry.traceTracker.get());
                }
                break;
            }

@@ -3622,7 +3675,11 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                    LOG(INFO) << "Publishing " << *dispatchEntry << " to "
                              << connection->getInputChannelName();
                }
                const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
                status = publishMotionEvent(*connection, *dispatchEntry);
                if (mTracer) {
                    mTracer->traceEventDispatch(*dispatchEntry, motionEntry.traceTracker.get());
                }
                break;
            }

@@ -4304,6 +4361,9 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
                                           args.deviceId, args.source, args.displayId, policyFlags,
                                           args.action, flags, keyCode, args.scanCode, metaState,
                                           repeatCount, args.downTime);
        if (mTracer) {
            newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
        }

        needWake = enqueueInboundEventLocked(std::move(newEntry));
        mLock.unlock();
@@ -4430,6 +4490,9 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
                                              args.yPrecision, args.xCursorPosition,
                                              args.yCursorPosition, args.downTime,
                                              args.pointerProperties, args.pointerCoords);
        if (mTracer) {
            newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
        }

        if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
            IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
@@ -4617,6 +4680,9 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev
                                               incomingKey.getScanCode(), metaState,
                                               incomingKey.getRepeatCount(),
                                               incomingKey.getDownTime());
            if (mTracer) {
                injectedEntry->traceTracker = mTracer->traceInboundEvent(*injectedEntry);
            }
            injectedEntries.push(std::move(injectedEntry));
            break;
        }
@@ -4674,6 +4740,9 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev
                                                                             samplePointerCoords +
                                                                                     pointerCount));
            transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
            if (mTracer) {
                injectedEntry->traceTracker = mTracer->traceInboundEvent(*injectedEntry);
            }
            injectedEntries.push(std::move(injectedEntry));
            for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
                sampleEventTimes += 1;
@@ -5763,6 +5832,8 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
                         ns2ms(mConfig.keyRepeatTimeout));
    dump += mLatencyTracker.dump(INDENT2);
    dump += mLatencyAggregator.dump(INDENT2);
    dump += INDENT "InputTracer: ";
    dump += mTracer == nullptr ? "Disabled" : "Enabled";
}

void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
+8 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#include "Monitor.h"
#include "TouchState.h"
#include "TouchedWindow.h"
#include "trace/InputTracerInterface.h"
#include "trace/InputTracingBackendInterface.h"

#include <attestation/HmacKeyManager.h>
#include <gui/InputApplication.h>
@@ -82,6 +84,9 @@ public:
    static constexpr bool kDefaultInTouchMode = true;

    explicit InputDispatcher(InputDispatcherPolicyInterface& policy);
    // Constructor used for testing.
    explicit InputDispatcher(InputDispatcherPolicyInterface&,
                             std::unique_ptr<trace::InputTracingBackendInterface>);
    ~InputDispatcher() override;

    void dump(std::string& dump) const override;
@@ -171,6 +176,9 @@ private:
    std::condition_variable mDispatcherIsAlive;
    mutable std::condition_variable mDispatcherEnteredIdle;

    // Input event tracer. The tracer will only exist on builds where input tracing is allowed.
    std::unique_ptr<trace::InputTracerInterface> mTracer GUARDED_BY(mLock);

    sp<Looper> mLooper;

    std::shared_ptr<const EventEntry> mPendingEvent GUARDED_BY(mLock);
+32 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

namespace android::inputdispatcher::trace {

/**
 * A tracker used to track the lifecycle of a traced input event.
 * The tracker should be stored inside the traced event. When the event goes out of scope after
 * the dispatcher has finished processing it, the tracker will call back into the tracer to
 * initiate cleanup.
 */
class EventTrackerInterface {
public:
    virtual ~EventTrackerInterface() = default;
};

} // namespace android::inputdispatcher::trace
Loading