1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.classifier; 18 19 import static com.android.systemui.classifier.FalsingModule.SINGLE_TAP_TOUCH_SLOP; 20 21 import android.view.MotionEvent; 22 23 import java.util.List; 24 25 import javax.inject.Inject; 26 import javax.inject.Named; 27 28 /** 29 * Falsing classifier that accepts or rejects a single gesture as a tap. 30 */ 31 public class SingleTapClassifier extends FalsingClassifier { 32 private final float mTouchSlop; 33 34 @Inject SingleTapClassifier(FalsingDataProvider dataProvider, @Named(SINGLE_TAP_TOUCH_SLOP) float touchSlop)35 SingleTapClassifier(FalsingDataProvider dataProvider, 36 @Named(SINGLE_TAP_TOUCH_SLOP) float touchSlop) { 37 super(dataProvider); 38 mTouchSlop = touchSlop; 39 } 40 41 @Override calculateFalsingResult( @lassifier.InteractionType int interactionType, double historyBelief, double historyConfidence)42 Result calculateFalsingResult( 43 @Classifier.InteractionType int interactionType, 44 double historyBelief, double historyConfidence) { 45 return isTap(getRecentMotionEvents(), 0.5); 46 } 47 48 /** Given a list of {@link android.view.MotionEvent}'s, returns true if the look like a tap. */ isTap(List<MotionEvent> motionEvents, double falsePenalty)49 public Result isTap(List<MotionEvent> motionEvents, double falsePenalty) { 50 if (motionEvents.isEmpty()) { 51 return falsed(0, "no motion events"); 52 } 53 float downX = motionEvents.get(0).getX(); 54 float downY = motionEvents.get(0).getY(); 55 56 for (MotionEvent event : motionEvents) { 57 String reason; 58 if (Math.abs(event.getX() - downX) >= mTouchSlop) { 59 reason = "dX too big for a tap: " 60 + Math.abs(event.getX() - downX) 61 + "vs " 62 + mTouchSlop; 63 return falsed(falsePenalty, reason); 64 } else if (Math.abs(event.getY() - downY) >= mTouchSlop) { 65 reason = "dY too big for a tap: " 66 + Math.abs(event.getY() - downY) 67 + " vs " 68 + mTouchSlop; 69 return falsed(falsePenalty, reason); 70 } 71 } 72 return Result.passed(0); 73 } 74 } 75