Loading include/input/InputConsumerNoResampling.h +18 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <functional> #include <map> #include <memory> #include <optional> Loading Loading @@ -75,12 +76,13 @@ public: * the event is ready to consume. * @param looper needs to be sp and not shared_ptr because it inherits from * RefBase * @param resampler the resampling strategy to use. If null, no resampling will be * performed. * @param resamplerCreator callable that returns the resampling strategy to be used. If null, no * resampling will be performed. resamplerCreator must never return nullptr. */ explicit InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler); explicit InputConsumerNoResampling( const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::function<std::unique_ptr<Resampler>()> resamplerCreator); ~InputConsumerNoResampling(); Loading Loading @@ -117,7 +119,13 @@ private: std::shared_ptr<InputChannel> mChannel; sp<Looper> mLooper; InputConsumerCallbacks& mCallbacks; std::unique_ptr<Resampler> mResampler; const std::function<std::unique_ptr<Resampler>()> mResamplerCreator; /** * A map to manage multidevice resampling. Each contained resampler is never null. This map is * only modified by handleMessages. */ std::map<DeviceId, std::unique_ptr<Resampler>> mResamplers; // Looper-related infrastructure /** Loading Loading @@ -190,7 +198,10 @@ private: /** * Batch messages that can be batched. When an unbatchable message is encountered, send it * to the InputConsumerCallbacks immediately. If there are batches remaining, * notify InputConsumerCallbacks. * notify InputConsumerCallbacks. If a resampleable ACTION_DOWN message is received, then a * resampler is inserted for that deviceId in mResamplers. If a resampleable ACTION_UP or * ACTION_CANCEL message is received then the resampler associated to that deviceId is erased * from mResamplers. */ void handleMessages(std::vector<InputMessage>&& messages); /** Loading include/input/Resampler.h +0 −6 Original line number Diff line number Diff line Loading @@ -91,12 +91,6 @@ private: } }; /** * Keeps track of the previous MotionEvent deviceId to enable comparison between the previous * and the current deviceId. */ std::optional<DeviceId> mPreviousDeviceId; /** * Up to two latest samples from MotionEvent. Updated every time resampleMotionEvent is called. * Note: We store up to two samples in order to simplify the implementation. Although, Loading libs/binder/tests/binderRpcTest.cpp +0 −9 Original line number Diff line number Diff line Loading @@ -1544,15 +1544,6 @@ TEST_F(BinderARpcNdk, ARpcNoDataNoInfoOnDeleteCallback) { ABinderRpc_Accessor_delete(accessor); } TEST_F(BinderARpcNdk, ARpcDoubleRemoveProvider) { ABinderRpc_AccessorProvider* provider = ABinderRpc_registerAccessorProvider(getAccessor, kARpcSupportedServices, kARpcNumSupportedServices, nullptr, nullptr); ASSERT_NE(nullptr, provider); ABinderRpc_unregisterAccessorProvider(provider); EXPECT_DEATH(ABinderRpc_unregisterAccessorProvider(provider), " was already unregistered"); } TEST_F(BinderARpcNdk, ARpcNullArgs_ConnectionInfo_new) { sockaddr_storage addr; EXPECT_EQ(nullptr, ABinderRpc_ConnectionInfo_new(reinterpret_cast<const sockaddr*>(&addr), 0)); Loading libs/input/InputConsumerNoResampling.cpp +42 −23 Original line number Diff line number Diff line Loading @@ -17,8 +17,6 @@ #define LOG_TAG "InputConsumerNoResampling" #define ATRACE_TAG ATRACE_TAG_INPUT #include <chrono> #include <inttypes.h> #include <android-base/logging.h> Loading @@ -39,6 +37,8 @@ namespace { using std::chrono::nanoseconds; using android::base::Result; /** * Log debug messages relating to the consumer end of the transport channel. * Enable this via "adb shell setprop log.tag.InputTransportConsumer DEBUG" (requires restart) Loading Loading @@ -169,24 +169,18 @@ InputMessage createTimelineMessage(int32_t inputEventId, nsecs_t gpuCompletedTim msg.body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = presentTime; return msg; } bool isPointerEvent(const MotionEvent& motionEvent) { return (motionEvent.getSource() & AINPUT_SOURCE_CLASS_POINTER) == AINPUT_SOURCE_CLASS_POINTER; } } // namespace using android::base::Result; // --- InputConsumerNoResampling --- InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerNoResampling::InputConsumerNoResampling( const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler) std::function<std::unique_ptr<Resampler>()> resamplerCreator) : mChannel{channel}, mLooper{looper}, mCallbacks{callbacks}, mResampler{std::move(resampler)}, mResamplerCreator{std::move(resamplerCreator)}, mFdEvents(0) { LOG_ALWAYS_FATAL_IF(mLooper == nullptr); mCallback = sp<LooperEventCallback>::make( Loading Loading @@ -319,7 +313,6 @@ void InputConsumerNoResampling::setFdEvents(int events) { } void InputConsumerNoResampling::handleMessages(std::vector<InputMessage>&& messages) { // TODO(b/297226446) : add resampling for (const InputMessage& msg : messages) { if (msg.header.type == InputMessage::Type::MOTION) { const int32_t action = msg.body.motion.action; Loading @@ -329,12 +322,31 @@ void InputConsumerNoResampling::handleMessages(std::vector<InputMessage>&& messa action == AMOTION_EVENT_ACTION_HOVER_MOVE) && (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER) || isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK)); const bool canResample = (mResamplerCreator != nullptr) && (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER)); if (canResample) { if (action == AMOTION_EVENT_ACTION_DOWN) { if (std::unique_ptr<Resampler> resampler = mResamplerCreator(); resampler != nullptr) { const auto [_, inserted] = mResamplers.insert(std::pair(deviceId, std::move(resampler))); LOG_IF(WARNING, !inserted) << deviceId << "already exists in mResamplers"; } } } if (batchableEvent) { // add it to batch mBatches[deviceId].emplace(msg); } else { // consume all pending batches for this device immediately consumeBatchedInputEvents(deviceId, /*requestedFrameTime=*/std::nullopt); if (canResample && (action == AMOTION_EVENT_ACTION_UP || action == AMOTION_EVENT_ACTION_CANCEL)) { LOG_IF(INFO, mResamplers.erase(deviceId) == 0) << deviceId << "does not exist in mResamplers"; } handleMessage(msg); } } else { Loading Loading @@ -456,8 +468,13 @@ InputConsumerNoResampling::createBatchedMotionEvent(const nsecs_t requestedFrame std::queue<InputMessage>& messages) { std::unique_ptr<MotionEvent> motionEvent; std::optional<uint32_t> firstSeqForBatch; const nanoseconds resampleLatency = (mResampler != nullptr) ? mResampler->getResampleLatency() : nanoseconds{0}; LOG_IF(FATAL, messages.empty()) << "messages queue is empty!"; const DeviceId deviceId = messages.front().body.motion.deviceId; const auto resampler = mResamplers.find(deviceId); const nanoseconds resampleLatency = (resampler != mResamplers.cend()) ? resampler->second->getResampleLatency() : nanoseconds{0}; const nanoseconds adjustedFrameTime = nanoseconds{requestedFrameTime} - resampleLatency; while (!messages.empty() && Loading @@ -474,15 +491,17 @@ InputConsumerNoResampling::createBatchedMotionEvent(const nsecs_t requestedFrame } messages.pop(); } // Check if resampling should be performed. if (motionEvent != nullptr && isPointerEvent(*motionEvent) && mResampler != nullptr) { InputMessage* futureSample = nullptr; if (!messages.empty()) { futureSample = &messages.front(); } mResampler->resampleMotionEvent(nanoseconds{requestedFrameTime}, *motionEvent, if ((motionEvent != nullptr) && (resampler != mResamplers.cend())) { resampler->second->resampleMotionEvent(nanoseconds{requestedFrameTime}, *motionEvent, futureSample); } return std::make_pair(std::move(motionEvent), firstSeqForBatch); } Loading libs/input/Resampler.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -247,11 +247,6 @@ nanoseconds LegacyResampler::getResampleLatency() const { void LegacyResampler::resampleMotionEvent(nanoseconds frameTime, MotionEvent& motionEvent, const InputMessage* futureSample) { if (mPreviousDeviceId && *mPreviousDeviceId != motionEvent.getDeviceId()) { mLatestSamples.clear(); } mPreviousDeviceId = motionEvent.getDeviceId(); const nanoseconds resampleTime = frameTime - RESAMPLE_LATENCY; updateLatestSamples(motionEvent); Loading Loading
include/input/InputConsumerNoResampling.h +18 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <functional> #include <map> #include <memory> #include <optional> Loading Loading @@ -75,12 +76,13 @@ public: * the event is ready to consume. * @param looper needs to be sp and not shared_ptr because it inherits from * RefBase * @param resampler the resampling strategy to use. If null, no resampling will be * performed. * @param resamplerCreator callable that returns the resampling strategy to be used. If null, no * resampling will be performed. resamplerCreator must never return nullptr. */ explicit InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler); explicit InputConsumerNoResampling( const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::function<std::unique_ptr<Resampler>()> resamplerCreator); ~InputConsumerNoResampling(); Loading Loading @@ -117,7 +119,13 @@ private: std::shared_ptr<InputChannel> mChannel; sp<Looper> mLooper; InputConsumerCallbacks& mCallbacks; std::unique_ptr<Resampler> mResampler; const std::function<std::unique_ptr<Resampler>()> mResamplerCreator; /** * A map to manage multidevice resampling. Each contained resampler is never null. This map is * only modified by handleMessages. */ std::map<DeviceId, std::unique_ptr<Resampler>> mResamplers; // Looper-related infrastructure /** Loading Loading @@ -190,7 +198,10 @@ private: /** * Batch messages that can be batched. When an unbatchable message is encountered, send it * to the InputConsumerCallbacks immediately. If there are batches remaining, * notify InputConsumerCallbacks. * notify InputConsumerCallbacks. If a resampleable ACTION_DOWN message is received, then a * resampler is inserted for that deviceId in mResamplers. If a resampleable ACTION_UP or * ACTION_CANCEL message is received then the resampler associated to that deviceId is erased * from mResamplers. */ void handleMessages(std::vector<InputMessage>&& messages); /** Loading
include/input/Resampler.h +0 −6 Original line number Diff line number Diff line Loading @@ -91,12 +91,6 @@ private: } }; /** * Keeps track of the previous MotionEvent deviceId to enable comparison between the previous * and the current deviceId. */ std::optional<DeviceId> mPreviousDeviceId; /** * Up to two latest samples from MotionEvent. Updated every time resampleMotionEvent is called. * Note: We store up to two samples in order to simplify the implementation. Although, Loading
libs/binder/tests/binderRpcTest.cpp +0 −9 Original line number Diff line number Diff line Loading @@ -1544,15 +1544,6 @@ TEST_F(BinderARpcNdk, ARpcNoDataNoInfoOnDeleteCallback) { ABinderRpc_Accessor_delete(accessor); } TEST_F(BinderARpcNdk, ARpcDoubleRemoveProvider) { ABinderRpc_AccessorProvider* provider = ABinderRpc_registerAccessorProvider(getAccessor, kARpcSupportedServices, kARpcNumSupportedServices, nullptr, nullptr); ASSERT_NE(nullptr, provider); ABinderRpc_unregisterAccessorProvider(provider); EXPECT_DEATH(ABinderRpc_unregisterAccessorProvider(provider), " was already unregistered"); } TEST_F(BinderARpcNdk, ARpcNullArgs_ConnectionInfo_new) { sockaddr_storage addr; EXPECT_EQ(nullptr, ABinderRpc_ConnectionInfo_new(reinterpret_cast<const sockaddr*>(&addr), 0)); Loading
libs/input/InputConsumerNoResampling.cpp +42 −23 Original line number Diff line number Diff line Loading @@ -17,8 +17,6 @@ #define LOG_TAG "InputConsumerNoResampling" #define ATRACE_TAG ATRACE_TAG_INPUT #include <chrono> #include <inttypes.h> #include <android-base/logging.h> Loading @@ -39,6 +37,8 @@ namespace { using std::chrono::nanoseconds; using android::base::Result; /** * Log debug messages relating to the consumer end of the transport channel. * Enable this via "adb shell setprop log.tag.InputTransportConsumer DEBUG" (requires restart) Loading Loading @@ -169,24 +169,18 @@ InputMessage createTimelineMessage(int32_t inputEventId, nsecs_t gpuCompletedTim msg.body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = presentTime; return msg; } bool isPointerEvent(const MotionEvent& motionEvent) { return (motionEvent.getSource() & AINPUT_SOURCE_CLASS_POINTER) == AINPUT_SOURCE_CLASS_POINTER; } } // namespace using android::base::Result; // --- InputConsumerNoResampling --- InputConsumerNoResampling::InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerNoResampling::InputConsumerNoResampling( const std::shared_ptr<InputChannel>& channel, sp<Looper> looper, InputConsumerCallbacks& callbacks, std::unique_ptr<Resampler> resampler) std::function<std::unique_ptr<Resampler>()> resamplerCreator) : mChannel{channel}, mLooper{looper}, mCallbacks{callbacks}, mResampler{std::move(resampler)}, mResamplerCreator{std::move(resamplerCreator)}, mFdEvents(0) { LOG_ALWAYS_FATAL_IF(mLooper == nullptr); mCallback = sp<LooperEventCallback>::make( Loading Loading @@ -319,7 +313,6 @@ void InputConsumerNoResampling::setFdEvents(int events) { } void InputConsumerNoResampling::handleMessages(std::vector<InputMessage>&& messages) { // TODO(b/297226446) : add resampling for (const InputMessage& msg : messages) { if (msg.header.type == InputMessage::Type::MOTION) { const int32_t action = msg.body.motion.action; Loading @@ -329,12 +322,31 @@ void InputConsumerNoResampling::handleMessages(std::vector<InputMessage>&& messa action == AMOTION_EVENT_ACTION_HOVER_MOVE) && (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER) || isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK)); const bool canResample = (mResamplerCreator != nullptr) && (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER)); if (canResample) { if (action == AMOTION_EVENT_ACTION_DOWN) { if (std::unique_ptr<Resampler> resampler = mResamplerCreator(); resampler != nullptr) { const auto [_, inserted] = mResamplers.insert(std::pair(deviceId, std::move(resampler))); LOG_IF(WARNING, !inserted) << deviceId << "already exists in mResamplers"; } } } if (batchableEvent) { // add it to batch mBatches[deviceId].emplace(msg); } else { // consume all pending batches for this device immediately consumeBatchedInputEvents(deviceId, /*requestedFrameTime=*/std::nullopt); if (canResample && (action == AMOTION_EVENT_ACTION_UP || action == AMOTION_EVENT_ACTION_CANCEL)) { LOG_IF(INFO, mResamplers.erase(deviceId) == 0) << deviceId << "does not exist in mResamplers"; } handleMessage(msg); } } else { Loading Loading @@ -456,8 +468,13 @@ InputConsumerNoResampling::createBatchedMotionEvent(const nsecs_t requestedFrame std::queue<InputMessage>& messages) { std::unique_ptr<MotionEvent> motionEvent; std::optional<uint32_t> firstSeqForBatch; const nanoseconds resampleLatency = (mResampler != nullptr) ? mResampler->getResampleLatency() : nanoseconds{0}; LOG_IF(FATAL, messages.empty()) << "messages queue is empty!"; const DeviceId deviceId = messages.front().body.motion.deviceId; const auto resampler = mResamplers.find(deviceId); const nanoseconds resampleLatency = (resampler != mResamplers.cend()) ? resampler->second->getResampleLatency() : nanoseconds{0}; const nanoseconds adjustedFrameTime = nanoseconds{requestedFrameTime} - resampleLatency; while (!messages.empty() && Loading @@ -474,15 +491,17 @@ InputConsumerNoResampling::createBatchedMotionEvent(const nsecs_t requestedFrame } messages.pop(); } // Check if resampling should be performed. if (motionEvent != nullptr && isPointerEvent(*motionEvent) && mResampler != nullptr) { InputMessage* futureSample = nullptr; if (!messages.empty()) { futureSample = &messages.front(); } mResampler->resampleMotionEvent(nanoseconds{requestedFrameTime}, *motionEvent, if ((motionEvent != nullptr) && (resampler != mResamplers.cend())) { resampler->second->resampleMotionEvent(nanoseconds{requestedFrameTime}, *motionEvent, futureSample); } return std::make_pair(std::move(motionEvent), firstSeqForBatch); } Loading
libs/input/Resampler.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -247,11 +247,6 @@ nanoseconds LegacyResampler::getResampleLatency() const { void LegacyResampler::resampleMotionEvent(nanoseconds frameTime, MotionEvent& motionEvent, const InputMessage* futureSample) { if (mPreviousDeviceId && *mPreviousDeviceId != motionEvent.getDeviceId()) { mLatestSamples.clear(); } mPreviousDeviceId = motionEvent.getDeviceId(); const nanoseconds resampleTime = frameTime - RESAMPLE_LATENCY; updateLatestSamples(motionEvent); Loading