summaryrefslogtreecommitdiff
path: root/services/inputflinger/reader/mapper/SlopController.cpp
blob: d55df511e1f7535db7e411c41fd8622afaa00d36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * Copyright 2023 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.
 */

// clang-format off
#include "../Macros.h"
// clang-format on

#include "SlopController.h"

namespace {
int signOf(float value) {
    if (value == 0) return 0;
    if (value > 0) return 1;
    return -1;
}
} // namespace

namespace android {

SlopController::SlopController(float slopThreshold, nsecs_t slopDurationNanos)
      : mSlopThreshold(slopThreshold), mSlopDurationNanos(slopDurationNanos) {}

float SlopController::consumeEvent(nsecs_t eventTimeNanos, float value) {
    if (mSlopDurationNanos == 0) {
        return value;
    }

    if (shouldResetSlopTracking(eventTimeNanos, value)) {
        mCumulativeValue = 0;
        mHasSlopBeenMet = false;
    }

    mLastEventTimeNanos = eventTimeNanos;

    if (mHasSlopBeenMet) {
        // Since slop has already been met, we know that all of the current value would pass the
        // slop threshold. So return that, without any further processing.
        return value;
    }

    mCumulativeValue += value;

    if (abs(mCumulativeValue) >= mSlopThreshold) {
        ALOGD("SlopController: did not drop event with value %.3f", value);
        mHasSlopBeenMet = true;
        // Return the amount of value that exceeds the slop.
        return signOf(value) * (abs(mCumulativeValue) - mSlopThreshold);
    }

    ALOGD("SlopController: dropping event with value %.3f", value);
    return 0;
}

bool SlopController::shouldResetSlopTracking(nsecs_t eventTimeNanos, float value) const {
    const nsecs_t ageNanos = eventTimeNanos - mLastEventTimeNanos;
    if (ageNanos >= mSlopDurationNanos) {
        return true;
    }
    if (value == 0) {
        return false;
    }
    if (signOf(mCumulativeValue) != signOf(value)) {
        return true;
    }
    return false;
}

} // namespace android