blob: 774ff9eb5bd85cb6255d053922d6e65fa6549852 [file] [log] [blame]
// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <gtest/gtest.h> // for FRIEND_TEST
#include "gestures/include/filter_interpreter.h"
#include "gestures/include/finger_metrics.h"
#include "gestures/include/gestures.h"
#include "gestures/include/map.h"
#include "gestures/include/prop_registry.h"
#include "gestures/include/set.h"
#include "gestures/include/tracer.h"
#ifndef GESTURES_FINGER_MERGE_FILTER_INTERPRETER_H_
#define GESTURES_FINGER_MERGE_FILTER_INTERPRETER_H_
namespace gestures {
// This interpreter mainly detects finger merging and mark the merging
// finger(s) with a new flag GESTURE_FINGER_MERGE. The flag can be used
// in immediateinterpreter to suppress cursor jumps/moves caused by the
// merging/merged finger(s).
class FingerMergeFilterInterpreter : public FilterInterpreter {
public:
FingerMergeFilterInterpreter(PropRegistry* prop_reg, Interpreter* next,
Tracer* tracer);
virtual ~FingerMergeFilterInterpreter() {}
protected:
virtual void SyncInterpretImpl(HardwareState* hwstate, stime_t* timeout);
private:
// Detects finger merge and appends GESTURE_FINGER_MERGE flag for a merged
// finger or close fingers
void UpdateFingerMergeState(const HardwareState& hwstate);
bool IsSuspiciousAngle(const FingerState& fs) const;
struct Start {
float position_x;
float position_y;
stime_t start_time;
bool operator==(const Start& that) const {
return position_x == that.position_x &&
position_y == that.position_y &&
start_time == that.start_time;
}
bool operator!=(const Start& that) const {
return !(*this == that);
}
};
// Info about each contact's initial state
map<short, Start, kMaxFingers> start_info_;
set<short, kMaxFingers> merge_tracking_ids_;
// Fingers that should never merge, as we've determined they aren't a merge
set<short, kMaxFingers> never_merge_ids_;
map<short, float, kMaxFingers> prev_x_displacement_;
map<short, float, kMaxFingers> prev2_x_displacement_;
// Flag to turn on/off the finger merge filter
BoolProperty finger_merge_filter_enable_;
// Distance threshold for close fingers
DoubleProperty merge_distance_threshold_;
// Maximum pressure value of a merged finger candidate
DoubleProperty max_pressure_threshold_;
// Min pressure of a merged finger candidate
DoubleProperty min_pressure_threshold_;
// Minimum touch major of a merged finger candidate
DoubleProperty min_major_threshold_;
// More criteria for filtering out false positives:
// The touch major of a merged finger could be merged_major_pressure_ratio_
// times of its pressure value at least or a merged finger could have a
// very high touch major
DoubleProperty merged_major_pressure_ratio_;
DoubleProperty merged_major_threshold_;
// We require that when a finger has displaced in the X direction more than
// x_jump_min_displacement_, the next frame it must be at
// x_jump_max_displacement_, else it's not considered a merged finger.
DoubleProperty x_jump_min_displacement_;
DoubleProperty x_jump_max_displacement_;
// If a contact has displaced from the start position more than
// suspicious_angle_min_displacement_, we require it to be at a particular
// angle relative to the start position.
DoubleProperty suspicious_angle_min_displacement_;
// If a contact exceeds any of these (movement in a direction or age),
// it is not marked as a merged contact.
DoubleProperty max_x_move_;
DoubleProperty max_y_move_;
DoubleProperty max_age_;
};
}
#endif