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

Commit 1fcb0cdd authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12397640 from c1ff18a4 to 24Q4-release

Change-Id: I85f7ef25efca5347a1d72b2fe6ebe4133f2ee1f4
parents 7879747f c1ff18a4
Loading
Loading
Loading
Loading
+35 −26
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@

#pragma once

#include <map>
#include <memory>
#include <optional>

#include <input/Input.h>
#include <input/InputTransport.h>
#include <input/LooperInterface.h>
#include <input/Resampler.h>
#include <utils/Looper.h>

@@ -36,7 +40,7 @@ public:
    /**
     * When you receive this callback, you must (eventually) call "consumeBatchedInputEvents".
     * If you don't want batching, then call "consumeBatchedInputEvents" immediately with
     * std::nullopt frameTime to receive the pending motion event(s).
     * std::nullopt requestedFrameTime to receive the pending motion event(s).
     * @param pendingBatchSource the source of the pending batch.
     */
    virtual void onBatchedInputEventPending(int32_t pendingBatchSource) = 0;
@@ -66,16 +70,6 @@ public:
 */
class InputConsumerNoResampling final {
public:
    /**
     * This constructor is exclusively for test code. Any real use of InputConsumerNoResampling must
     * use the constructor that takes an sp<Looper> parameter instead of
     * std::shared_ptr<LooperInterface>.
     */
    explicit InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel,
                                       std::shared_ptr<LooperInterface> looper,
                                       InputConsumerCallbacks& callbacks,
                                       std::unique_ptr<Resampler> resampler);

    /**
     * @param callbacks are used to interact with InputConsumerNoResampling. They're called whenever
     * the event is ready to consume.
@@ -96,15 +90,17 @@ public:
    void finishInputEvent(uint32_t seq, bool handled);
    void reportTimeline(int32_t inputEventId, nsecs_t gpuCompletedTime, nsecs_t presentTime);
    /**
     * If you want to consume all events immediately (disable batching), the you still must call
     * this. For frameTime, use a std::nullopt.
     * @param frameTime the time up to which consume the events. When there's double (or triple)
     * buffering, you may want to not consume all events currently available, because you could be
     * still working on an older frame, but there could already have been events that arrived that
     * are more recent.
     * If you want to consume all events immediately (disable batching), then you still must call
     * this. For requestedFrameTime, use a std::nullopt. It is not guaranteed that the consumption
     * will occur at requestedFrameTime. The resampling strategy may modify it.
     * @param requestedFrameTime the time up to which consume the events. When there's double (or
     * triple) buffering, you may want to not consume all events currently available, because you
     * could be still working on an older frame, but there could already have been events that
     * arrived that are more recent.
     * @return whether any events were actually consumed
     */
    bool consumeBatchedInputEvents(std::optional<nsecs_t> frameTime);
    bool consumeBatchedInputEvents(std::optional<nsecs_t> requestedFrameTime);

    /**
     * Returns true when there is *likely* a pending batch or a pending event in the channel.
     *
@@ -119,7 +115,7 @@ public:

private:
    std::shared_ptr<InputChannel> mChannel;
    std::shared_ptr<LooperInterface> mLooper;
    sp<Looper> mLooper;
    InputConsumerCallbacks& mCallbacks;
    std::unique_ptr<Resampler> mResampler;

@@ -200,20 +196,33 @@ private:
    /**
     * Batched InputMessages, per deviceId.
     * For each device, we are storing a queue of batched messages. These will all be collapsed into
     * a single MotionEvent (up to a specific frameTime) when the consumer calls
     * a single MotionEvent (up to a specific requestedFrameTime) when the consumer calls
     * `consumeBatchedInputEvents`.
     */
    std::map<DeviceId, std::queue<InputMessage>> mBatches;
    /**
     * Creates a MotionEvent by consuming samples from the provided queue. If one message has
     * eventTime > frameTime, all subsequent messages in the queue will be skipped. It is assumed
     * that messages are queued in chronological order. In other words, only events that occurred
     * prior to the requested frameTime will be consumed.
     * @param frameTime the time up to which to consume events
     * eventTime > adjustedFrameTime, all subsequent messages in the queue will be skipped. It is
     * assumed that messages are queued in chronological order. In other words, only events that
     * occurred prior to the adjustedFrameTime will be consumed.
     * @param requestedFrameTime the time up to which to consume events.
     * @param messages the queue of messages to consume from
     */
    std::pair<std::unique_ptr<MotionEvent>, std::optional<uint32_t>> createBatchedMotionEvent(
            const nsecs_t frameTime, std::queue<InputMessage>& messages);
            const nsecs_t requestedFrameTime, std::queue<InputMessage>& messages);

    /**
     * Consumes the batched input events, optionally allowing the caller to specify a device id
     * and/or requestedFrameTime threshold. It is not guaranteed that consumption will occur at
     * requestedFrameTime.
     * @param deviceId The device id from which to consume events. If std::nullopt, consumes events
     * from any device id.
     * @param requestedFrameTime The time up to which consume the events. If std::nullopt, consumes
     * input events with any timestamp.
     * @return Whether or not any events were consumed.
     */
    bool consumeBatchedInputEvents(std::optional<DeviceId> deviceId,
                                   std::optional<nsecs_t> requestedFrameTime);
    /**
     * A map from a single sequence number to several sequence numbers. This is needed because of
     * batching. When batching is enabled, a single MotionEvent will contain several samples. Each

include/input/LooperInterface.h

deleted100644 → 0
+0 −39
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

#include <utils/Looper.h>
#include <utils/StrongPointer.h>

namespace android {

/**
 * LooperInterface allows the use of TestLooper in InputConsumerNoResampling without reassigning to
 * Looper. LooperInterface is needed to control how InputConsumerNoResampling consumes and batches
 * InputMessages.
 */
class LooperInterface {
public:
    virtual ~LooperInterface() = default;

    virtual int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback,
                      void* data) = 0;
    virtual int removeFd(int fd) = 0;

    virtual sp<Looper> getLooper() const = 0;
};
} // namespace android
+19 −14
Original line number Diff line number Diff line
@@ -232,6 +232,15 @@ static const void* printReturnCommand(std::ostream& out, const void* _cmd) {
    return cmd;
}

static void printReturnCommandParcel(std::ostream& out, const Parcel& parcel) {
    const void* cmds = parcel.data();
    out << "\t" << HexDump(cmds, parcel.dataSize()) << "\n";
    IF_LOG_COMMANDS() {
        const void* end = parcel.data() + parcel.dataSize();
        while (cmds < end) cmds = printReturnCommand(out, cmds);
    }
}

static const void* printCommand(std::ostream& out, const void* _cmd) {
    static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
    const int32_t* cmd = (const int32_t*)_cmd;
@@ -1235,13 +1244,15 @@ status_t IPCThreadState::talkWithDriver(bool doReceive)

    if (err >= NO_ERROR) {
        if (bwr.write_consumed > 0) {
            if (bwr.write_consumed < mOut.dataSize())
            if (bwr.write_consumed < mOut.dataSize()) {
                std::ostringstream logStream;
                printReturnCommandParcel(logStream, mIn);
                LOG_ALWAYS_FATAL("Driver did not consume write buffer. "
                                 "err: %s consumed: %zu of %zu",
                                 statusToString(err).c_str(),
                                 (size_t)bwr.write_consumed,
                                 mOut.dataSize());
            else {
                                 "err: %s consumed: %zu of %zu.\n"
                                 "Return command: %s",
                                 statusToString(err).c_str(), (size_t)bwr.write_consumed,
                                 mOut.dataSize(), logStream.str().c_str());
            } else {
                mOut.setDataSize(0);
                processPostWriteDerefs();
            }
@@ -1252,14 +1263,8 @@ status_t IPCThreadState::talkWithDriver(bool doReceive)
        }
        IF_LOG_COMMANDS() {
            std::ostringstream logStream;
            logStream << "Remaining data size: " << mOut.dataSize() << "\n";
            logStream << "Received commands from driver: ";
            const void* cmds = mIn.data();
            const void* end = mIn.data() + mIn.dataSize();
            logStream << "\t" << HexDump(cmds, mIn.dataSize()) << "\n";
            while (cmds < end) cmds = printReturnCommand(logStream, cmds);
            std::string message = logStream.str();
            ALOGI("%s", message.c_str());
            printReturnCommandParcel(logStream, mIn);
            ALOGI("%s", logStream.str().c_str());
        }
        return NO_ERROR;
    }
Loading