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

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

Merge "Add support for search modifier fallbacks" into main

parents bcbec20c 523b461f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -125,10 +125,17 @@ struct KeyEntry : EventEntry {
    bool syntheticRepeat; // set to true for synthetic key repeats

    enum class InterceptKeyResult {
        // The interception result is unknown.
        UNKNOWN,
        // The event should be skipped and not sent to the application.
        SKIP,
        // The event should be sent to the application.
        CONTINUE,
        // The event should eventually be sent to the application, after a delay.
        TRY_AGAIN_LATER,
        // The event should not be initially sent to the application, but instead go through
        // post-processing to generate a fallback key event and then sent to the application.
        FALLBACK,
    };
    // These are special fields that may need to be modified while the event is being dispatched.
    mutable InterceptKeyResult interceptKeyResult; // set based on the interception result
+65 −2
Original line number Diff line number Diff line
@@ -952,7 +952,7 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
                                  new LatencyAggregatorWithHistograms()))
                        : std::move(std::unique_ptr<InputEventTimelineProcessor>(
                                  new LatencyAggregator()))),
        mLatencyTracker(*mInputEventTimelineProcessor) {
        mLatencyTracker(*mInputEventTimelineProcessor, mInputDevices) {
    mReporter = createInputReporter();

    mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
@@ -1961,11 +1961,74 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con
        }
    }

    if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::FALLBACK) {
        findAndDispatchFallbackEvent(currentTime, entry, inputTargets);
        // Drop the key.
        return true;
    }

    // Dispatch the key.
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
}

void InputDispatcher::findAndDispatchFallbackEvent(nsecs_t currentTime,
                                                   std::shared_ptr<const KeyEntry> entry,
                                                   std::vector<InputTarget>& inputTargets) {
    // Find the fallback associated with the incoming key event and dispatch it.
    KeyEvent event = createKeyEvent(*entry);
    const int32_t originalKeyCode = entry->keyCode;

    // Fetch the fallback event.
    KeyCharacterMap::FallbackAction fallback;
    for (const InputDeviceInfo& deviceInfo : mInputDevices) {
        if (deviceInfo.getId() == entry->deviceId) {
            const KeyCharacterMap* map = deviceInfo.getKeyCharacterMap();

            LOG_ALWAYS_FATAL_IF(map == nullptr, "No KeyCharacterMap for device %d",
                                entry->deviceId);
            map->getFallbackAction(entry->keyCode, entry->metaState, &fallback);
            break;
        }
    }

    if (fallback.keyCode == AKEYCODE_UNKNOWN) {
        // No fallback detected.
        return;
    }

    std::unique_ptr<KeyEntry> fallbackKeyEntry =
            std::make_unique<KeyEntry>(mIdGenerator.nextId(), entry->injectionState,
                                       event.getEventTime(), event.getDeviceId(), event.getSource(),
                                       event.getDisplayId(), entry->policyFlags, entry->action,
                                       event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
                                       fallback.keyCode, event.getScanCode(), /*metaState=*/0,
                                       event.getRepeatCount(), event.getDownTime());

    if (mTracer) {
        fallbackKeyEntry->traceTracker =
                mTracer->traceDerivedEvent(*fallbackKeyEntry, *entry->traceTracker);
    }

    for (const InputTarget& inputTarget : inputTargets) {
        std::shared_ptr<Connection> connection = inputTarget.connection;
        if (!connection->responsive || (connection->status != Connection::Status::NORMAL)) {
            return;
        }

        connection->inputState.setFallbackKey(originalKeyCode, fallback.keyCode);
        if (entry->action == AKEY_EVENT_ACTION_UP) {
            connection->inputState.removeFallbackKey(originalKeyCode);
        }

        if (mTracer) {
            mTracer->dispatchToTargetHint(*fallbackKeyEntry->traceTracker, inputTarget);
        }
        enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
                                                        std::move(fallbackKeyEntry), inputTarget);
    }
}

void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
    LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
            << prefix << "eventTime=" << entry.eventTime << ", deviceId=" << entry.deviceId
@@ -4346,7 +4409,7 @@ void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedA
    std::scoped_lock _l(mLock);
    // Reset key repeating in case a keyboard device was added or removed or something.
    resetKeyRepeatLocked();
    mLatencyTracker.setInputDevices(args.inputDeviceInfos);
    mInputDevices = args.inputDeviceInfos;
}

void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
+4 −0
Original line number Diff line number Diff line
@@ -918,10 +918,14 @@ private:
    std::unique_ptr<const KeyEntry> afterKeyEventLockedInterruptable(
            const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
            bool handled) REQUIRES(mLock);
    void findAndDispatchFallbackEvent(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
                                      std::vector<InputTarget>& inputTargets) REQUIRES(mLock);

    // Statistics gathering.
    nsecs_t mLastStatisticPushTime = 0;
    std::unique_ptr<InputEventTimelineProcessor> mInputEventTimelineProcessor GUARDED_BY(mLock);
    // Must outlive `mLatencyTracker`.
    std::vector<InputDeviceInfo> mInputDevices;
    LatencyTracker mLatencyTracker GUARDED_BY(mLock);
    void traceInboundQueueLengthLocked() REQUIRES(mLock);
    void traceOutboundQueueLength(const Connection& connection);
+3 −6
Original line number Diff line number Diff line
@@ -67,8 +67,9 @@ static void eraseByValue(std::multimap<K, V>& map, const V& value) {

} // namespace

LatencyTracker::LatencyTracker(InputEventTimelineProcessor& processor)
      : mTimelineProcessor(&processor) {}
LatencyTracker::LatencyTracker(InputEventTimelineProcessor& processor,
                               std::vector<InputDeviceInfo>& inputDevices)
      : mTimelineProcessor(&processor), mInputDevices(inputDevices) {}

void LatencyTracker::trackListener(const NotifyArgs& args) {
    if (const NotifyKeyArgs* keyArgs = std::get_if<NotifyKeyArgs>(&args)) {
@@ -248,8 +249,4 @@ std::string LatencyTracker::dump(const char* prefix) const {
            StringPrintf("%s  mEventTimes.size() = %zu\n", prefix, mEventTimes.size());
}

void LatencyTracker::setInputDevices(const std::vector<InputDeviceInfo>& inputDevices) {
    mInputDevices = inputDevices;
}

} // namespace android::inputdispatcher
+6 −3
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@

#include <map>
#include <unordered_map>
#include <vector>

#include <binder/IBinder.h>
#include <input/Input.h>
#include <input/InputDevice.h>

#include "InputEventTimeline.h"
#include "NotifyArgs.h"
@@ -41,8 +43,10 @@ public:
    /**
     * Create a LatencyTracker.
     * param reportingFunction: the function that will be called in order to report full latency.
     * param inputDevices: input devices relevant for tracking.
     */
    LatencyTracker(InputEventTimelineProcessor& processor);
    LatencyTracker(InputEventTimelineProcessor& processor,
                   std::vector<InputDeviceInfo>& inputDevices);
    /**
     * Start keeping track of an event identified by the args. This must be called first.
     * If duplicate events are encountered (events that have the same eventId), none of them will be
@@ -60,7 +64,6 @@ public:
                              std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);

    std::string dump(const char* prefix) const;
    void setInputDevices(const std::vector<InputDeviceInfo>& inputDevices);

private:
    /**
@@ -81,7 +84,7 @@ private:
    std::multimap<nsecs_t /*eventTime*/, int32_t /*inputEventId*/> mEventTimes;

    InputEventTimelineProcessor* mTimelineProcessor;
    std::vector<InputDeviceInfo> mInputDevices;
    std::vector<InputDeviceInfo>& mInputDevices;

    void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId,
                       const std::set<InputDeviceUsageSource>& sources, int32_t inputEventAction,
Loading