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

Commit 8a2e589e authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Override VelocityTracker strategy for non-differential axes only

VelocityTracker may use different strategies, depending on the system
flags. By default, the behaviour is like this:
AXIS_X -> lsq2
AXIS_Y -> lsq2
AXIS_SCROLL -> impulse

However, if we provide a specific strategy to VT, then things would
change. The new map would look like this:
AXIS_X -> provided strategy
AXIS_Y -> provided strategy
AXIS_SCROLL -> provided strategy

This works fine if the user specifies "impulse" as the desired strategy,
because impulse supports all of the axes.
However, lsq2 only works in non-differential mode.

The combination of "AXIS_SCROLL -> lsq2" is not allowed.

To fix this, we only allow the specified strategy to affect
non-differential axes.

This is fine, because currently, impulse is the only strategy that can
work in the differential mode.

To reproduce the issue:
1. Run `atest VelocityTrackerTest`. Test should pass, because the
   default strategy is being used.
2. Connect the device to internet
3. Reboot the device
4. Run `atest VelocityTrackerTest` again. Test should fail because the
   device would pick up an "lsq2" strategy value and then try to run the
   axis_scroll tests with it.

Bug: 295290374
Test: atest VelocityTrackerTest
Change-Id: I702a2a3e58db3ce2e0ff0c33122839a527eebab2
parent 18f8c58c
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ public:
        INT2 = 8,
        LEGACY = 9,
        MAX = LEGACY,
        ftl_last = LEGACY,
    };

    /*
@@ -81,8 +82,6 @@ public:
    // TODO(b/32830165): support axis-specific strategies.
    VelocityTracker(const Strategy strategy = Strategy::DEFAULT);

    ~VelocityTracker();

    /** Return true if the axis is supported for velocity tracking, false otherwise. */
    static bool isAxisSupported(int32_t axis);

+13 −19
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "VelocityTracker"

#include <android-base/logging.h>
#include <ftl/enum.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
@@ -148,27 +149,19 @@ static std::string matrixToString(const float* a, uint32_t m, uint32_t n, bool r
VelocityTracker::VelocityTracker(const Strategy strategy)
      : mLastEventTime(0), mCurrentPointerIdBits(0), mOverrideStrategy(strategy) {}

VelocityTracker::~VelocityTracker() {
}

bool VelocityTracker::isAxisSupported(int32_t axis) {
    return DEFAULT_STRATEGY_BY_AXIS.find(axis) != DEFAULT_STRATEGY_BY_AXIS.end();
}

void VelocityTracker::configureStrategy(int32_t axis) {
    const bool isDifferentialAxis = DIFFERENTIAL_AXES.find(axis) != DIFFERENTIAL_AXES.end();

    std::unique_ptr<VelocityTrackerStrategy> createdStrategy;
    if (mOverrideStrategy != VelocityTracker::Strategy::DEFAULT) {
        createdStrategy = createStrategy(mOverrideStrategy, /*deltaValues=*/isDifferentialAxis);
    } else {
        createdStrategy = createStrategy(DEFAULT_STRATEGY_BY_AXIS.at(axis),
    if (isDifferentialAxis || mOverrideStrategy == VelocityTracker::Strategy::DEFAULT) {
        // Do not allow overrides of strategies for differential axes, for now.
        mConfiguredStrategies[axis] = createStrategy(DEFAULT_STRATEGY_BY_AXIS.at(axis),
                                                     /*deltaValues=*/isDifferentialAxis);
    } else {
        mConfiguredStrategies[axis] = createStrategy(mOverrideStrategy, /*deltaValues=*/false);
    }

    LOG_ALWAYS_FATAL_IF(createdStrategy == nullptr,
                        "Could not create velocity tracker strategy for axis '%" PRId32 "'!", axis);
    mConfiguredStrategies[axis] = std::move(createdStrategy);
}

std::unique_ptr<VelocityTrackerStrategy> VelocityTracker::createStrategy(
@@ -216,6 +209,9 @@ std::unique_ptr<VelocityTrackerStrategy> VelocityTracker::createStrategy(
        default:
            break;
    }
    LOG(FATAL) << "Invalid strategy: " << ftl::enum_string(strategy)
               << ", deltaValues = " << deltaValues;

    return nullptr;
}

@@ -272,12 +268,10 @@ void VelocityTracker::addMovement(nsecs_t eventTime, int32_t pointerId, int32_t
    mConfiguredStrategies[axis]->addMovement(eventTime, pointerId, position);

    if (DEBUG_VELOCITY) {
        ALOGD("VelocityTracker: addMovement eventTime=%" PRId64 ", pointerId=%" PRId32
              ", activePointerId=%s",
              eventTime, pointerId, toString(mActivePointerId).c_str());

        ALOGD("  %d: axis=%d, position=%0.3f, velocity=%s", pointerId, axis, position,
              toString(getVelocity(axis, pointerId)).c_str());
        LOG(INFO) << "VelocityTracker: addMovement axis=" << MotionEvent::getLabel(axis)
                  << ", eventTime=" << eventTime << ", pointerId=" << pointerId
                  << ", activePointerId=" << toString(mActivePointerId) << ", position=" << position
                  << ", velocity=" << toString(getVelocity(axis, pointerId));
    }
}

+5 −0
Original line number Diff line number Diff line
@@ -278,6 +278,11 @@ static void computeAndCheckAxisScrollVelocity(
        const std::vector<std::pair<std::chrono::nanoseconds, float>>& motions,
        std::optional<float> targetVelocity) {
    checkVelocity(computeVelocity(strategy, motions, AMOTION_EVENT_AXIS_SCROLL), targetVelocity);
    // The strategy LSQ2 is not compatible with AXIS_SCROLL. In those situations, we should fall
    // back to a strategy that supports differential axes.
    checkVelocity(computeVelocity(VelocityTracker::Strategy::LSQ2, motions,
                                  AMOTION_EVENT_AXIS_SCROLL),
                  targetVelocity);
}

static void computeAndCheckQuadraticVelocity(const std::vector<PlanarMotionEventEntry>& motions,