Loading include/input/InputConsumerNoResampling.h +12 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <input/InputTransport.h> #include <input/LooperInterface.h> #include <input/Resampler.h> #include <utils/Looper.h> Loading Loading @@ -65,6 +66,16 @@ 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. Loading Loading @@ -108,7 +119,7 @@ public: private: std::shared_ptr<InputChannel> mChannel; sp<Looper> mLooper; std::shared_ptr<LooperInterface> mLooper; InputConsumerCallbacks& mCallbacks; std::unique_ptr<Resampler> mResampler; Loading include/input/InputTransport.h +6 −5 Original line number Diff line number Diff line Loading @@ -263,7 +263,7 @@ public: * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t sendMessage(const InputMessage* msg); virtual status_t sendMessage(const InputMessage* msg); /* Receive a message sent by the other endpoint. * Loading @@ -275,14 +275,14 @@ public: * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ android::base::Result<InputMessage> receiveMessage(); virtual android::base::Result<InputMessage> receiveMessage(); /* Tells whether there is a message in the channel available to be received. * * This is only a performance hint and may return false negative results. Clients should not * rely on availability of the message based on the return value. */ bool probablyHasInput() const; virtual bool probablyHasInput() const; /* Wait until there is a message in the channel. * Loading Loading @@ -323,11 +323,12 @@ public: */ sp<IBinder> getConnectionToken() const; protected: InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token); private: static std::unique_ptr<InputChannel> create(const std::string& name, android::base::unique_fd fd, sp<IBinder> token); InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token); }; /* Loading include/input/LooperInterface.h 0 → 100644 +39 −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 #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 libs/input/InputConsumerNoResampling.cpp +34 −10 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #define LOG_TAG "InputTransport" #define LOG_TAG "InputConsumerNoResampling" #define ATRACE_TAG ATRACE_TAG_INPUT #include <chrono> Loading @@ -33,8 +33,6 @@ #include <input/PrintTools.h> #include <input/TraceTools.h> namespace input_flags = com::android::input::flags; namespace android { namespace { Loading @@ -46,6 +44,27 @@ namespace { const bool DEBUG_TRANSPORT_CONSUMER = __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Consumer", ANDROID_LOG_INFO); /** * RealLooper is a wrapper of Looper. All the member functions exclusively call the internal looper. * This class' behavior is the same as Looper. */ class RealLooper final : public LooperInterface { public: RealLooper(sp<Looper> looper) : mLooper{looper} {} int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) override { return mLooper->addFd(fd, ident, events, callback, data); } int removeFd(int fd) override { return mLooper->removeFd(fd); } sp<Looper> getLooper() const override { return mLooper; } private: sp<Looper> mLooper; }; std::unique_ptr<KeyEvent> createKeyEvent(const InputMessage& msg) { std::unique_ptr<KeyEvent> event = std::make_unique<KeyEvent>(); event->initialize(msg.body.key.eventId, msg.body.key.deviceId, msg.body.key.source, Loading Loading @@ -173,22 +192,20 @@ InputMessage createTimelineMessage(int32_t inputEventId, nsecs_t gpuCompletedTim bool isPointerEvent(const MotionEvent& motionEvent) { return (motionEvent.getSource() & AINPUT_SOURCE_CLASS_POINTER) == AINPUT_SOURCE_CLASS_POINTER; } } // namespace using android::base::Result; using android::base::StringPrintf; // --- InputConsumerNoResampling --- InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, std::shared_ptr<LooperInterface> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler) : mChannel(channel), mLooper(looper), : mChannel{channel}, mLooper{looper}, mCallbacks(callbacks), mResampler(std::move(resampler)), mResampler{std::move(resampler)}, mFdEvents(0) { LOG_ALWAYS_FATAL_IF(mLooper == nullptr); mCallback = sp<LooperEventCallback>::make( Loading @@ -199,6 +216,13 @@ InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<Input setFdEvents(ALOOPER_EVENT_INPUT); } InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler) : InputConsumerNoResampling(channel, std::make_shared<RealLooper>(looper), callbacks, std::move(resampler)) {} InputConsumerNoResampling::~InputConsumerNoResampling() { ensureCalledOnLooperThread(__func__); consumeBatchedInputEvents(std::nullopt); Loading Loading @@ -513,7 +537,7 @@ bool InputConsumerNoResampling::consumeBatchedInputEvents( void InputConsumerNoResampling::ensureCalledOnLooperThread(const char* func) const { sp<Looper> callingThreadLooper = Looper::getForThread(); if (callingThreadLooper != mLooper) { if (callingThreadLooper != mLooper->getLooper()) { LOG(FATAL) << "The function " << func << " can only be called on the looper thread"; } } Loading libs/input/tests/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ cc_test { "BlockingQueue_test.cpp", "IdGenerator_test.cpp", "InputChannel_test.cpp", "InputConsumer_test.cpp", "InputDevice_test.cpp", "InputEvent_test.cpp", "InputPublisherAndConsumer_test.cpp", Loading @@ -25,6 +26,8 @@ cc_test { "MotionPredictorMetricsManager_test.cpp", "Resampler_test.cpp", "RingBuffer_test.cpp", "TestInputChannel.cpp", "TestLooper.cpp", "TfLiteMotionPredictor_test.cpp", "TouchResampling_test.cpp", "TouchVideoFrame_test.cpp", Loading Loading
include/input/InputConsumerNoResampling.h +12 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <input/InputTransport.h> #include <input/LooperInterface.h> #include <input/Resampler.h> #include <utils/Looper.h> Loading Loading @@ -65,6 +66,16 @@ 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. Loading Loading @@ -108,7 +119,7 @@ public: private: std::shared_ptr<InputChannel> mChannel; sp<Looper> mLooper; std::shared_ptr<LooperInterface> mLooper; InputConsumerCallbacks& mCallbacks; std::unique_ptr<Resampler> mResampler; Loading
include/input/InputTransport.h +6 −5 Original line number Diff line number Diff line Loading @@ -263,7 +263,7 @@ public: * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t sendMessage(const InputMessage* msg); virtual status_t sendMessage(const InputMessage* msg); /* Receive a message sent by the other endpoint. * Loading @@ -275,14 +275,14 @@ public: * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ android::base::Result<InputMessage> receiveMessage(); virtual android::base::Result<InputMessage> receiveMessage(); /* Tells whether there is a message in the channel available to be received. * * This is only a performance hint and may return false negative results. Clients should not * rely on availability of the message based on the return value. */ bool probablyHasInput() const; virtual bool probablyHasInput() const; /* Wait until there is a message in the channel. * Loading Loading @@ -323,11 +323,12 @@ public: */ sp<IBinder> getConnectionToken() const; protected: InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token); private: static std::unique_ptr<InputChannel> create(const std::string& name, android::base::unique_fd fd, sp<IBinder> token); InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token); }; /* Loading
include/input/LooperInterface.h 0 → 100644 +39 −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 #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
libs/input/InputConsumerNoResampling.cpp +34 −10 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #define LOG_TAG "InputTransport" #define LOG_TAG "InputConsumerNoResampling" #define ATRACE_TAG ATRACE_TAG_INPUT #include <chrono> Loading @@ -33,8 +33,6 @@ #include <input/PrintTools.h> #include <input/TraceTools.h> namespace input_flags = com::android::input::flags; namespace android { namespace { Loading @@ -46,6 +44,27 @@ namespace { const bool DEBUG_TRANSPORT_CONSUMER = __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Consumer", ANDROID_LOG_INFO); /** * RealLooper is a wrapper of Looper. All the member functions exclusively call the internal looper. * This class' behavior is the same as Looper. */ class RealLooper final : public LooperInterface { public: RealLooper(sp<Looper> looper) : mLooper{looper} {} int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) override { return mLooper->addFd(fd, ident, events, callback, data); } int removeFd(int fd) override { return mLooper->removeFd(fd); } sp<Looper> getLooper() const override { return mLooper; } private: sp<Looper> mLooper; }; std::unique_ptr<KeyEvent> createKeyEvent(const InputMessage& msg) { std::unique_ptr<KeyEvent> event = std::make_unique<KeyEvent>(); event->initialize(msg.body.key.eventId, msg.body.key.deviceId, msg.body.key.source, Loading Loading @@ -173,22 +192,20 @@ InputMessage createTimelineMessage(int32_t inputEventId, nsecs_t gpuCompletedTim bool isPointerEvent(const MotionEvent& motionEvent) { return (motionEvent.getSource() & AINPUT_SOURCE_CLASS_POINTER) == AINPUT_SOURCE_CLASS_POINTER; } } // namespace using android::base::Result; using android::base::StringPrintf; // --- InputConsumerNoResampling --- InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, std::shared_ptr<LooperInterface> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler) : mChannel(channel), mLooper(looper), : mChannel{channel}, mLooper{looper}, mCallbacks(callbacks), mResampler(std::move(resampler)), mResampler{std::move(resampler)}, mFdEvents(0) { LOG_ALWAYS_FATAL_IF(mLooper == nullptr); mCallback = sp<LooperEventCallback>::make( Loading @@ -199,6 +216,13 @@ InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<Input setFdEvents(ALOOPER_EVENT_INPUT); } InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler) : InputConsumerNoResampling(channel, std::make_shared<RealLooper>(looper), callbacks, std::move(resampler)) {} InputConsumerNoResampling::~InputConsumerNoResampling() { ensureCalledOnLooperThread(__func__); consumeBatchedInputEvents(std::nullopt); Loading Loading @@ -513,7 +537,7 @@ bool InputConsumerNoResampling::consumeBatchedInputEvents( void InputConsumerNoResampling::ensureCalledOnLooperThread(const char* func) const { sp<Looper> callingThreadLooper = Looper::getForThread(); if (callingThreadLooper != mLooper) { if (callingThreadLooper != mLooper->getLooper()) { LOG(FATAL) << "The function " << func << " can only be called on the looper thread"; } } Loading
libs/input/tests/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ cc_test { "BlockingQueue_test.cpp", "IdGenerator_test.cpp", "InputChannel_test.cpp", "InputConsumer_test.cpp", "InputDevice_test.cpp", "InputEvent_test.cpp", "InputPublisherAndConsumer_test.cpp", Loading @@ -25,6 +26,8 @@ cc_test { "MotionPredictorMetricsManager_test.cpp", "Resampler_test.cpp", "RingBuffer_test.cpp", "TestInputChannel.cpp", "TestLooper.cpp", "TfLiteMotionPredictor_test.cpp", "TouchResampling_test.cpp", "TouchVideoFrame_test.cpp", Loading