// Copyright 2013 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include // for FRIEND_TEST #include "include/filter_interpreter.h" #include "include/finger_metrics.h" #include "include/gestures.h" #include "include/prop_registry.h" #include "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 { FRIEND_TEST(FingerMergeFilterInterpreterTest, SimpleTest); 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 std::map start_info_; std::set merge_tracking_ids_; // Fingers that should never merge, as we've determined they aren't a merge std::set never_merge_ids_; std::map prev_x_displacement_; std::map 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