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.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.when; 22 23 import android.testing.AndroidTestingRunner; 24 import android.view.MotionEvent; 25 26 import androidx.test.filters.SmallTest; 27 28 import org.junit.After; 29 import org.junit.Before; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.mockito.Mock; 33 import org.mockito.MockitoAnnotations; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 @SmallTest 39 @RunWith(AndroidTestingRunner.class) 40 public class SingleTapClassifierTest extends ClassifierTest { 41 42 private static final int TOUCH_SLOP = 100; 43 44 private final List<MotionEvent> mMotionEvents = new ArrayList<>(); 45 46 @Mock 47 private FalsingDataProvider mDataProvider; 48 private SingleTapClassifier mClassifier; 49 50 @Before setup()51 public void setup() { 52 super.setup(); 53 MockitoAnnotations.initMocks(this); 54 mClassifier = new SingleTapClassifier(mDataProvider, TOUCH_SLOP); 55 } 56 57 @After tearDown()58 public void tearDown() { 59 for (MotionEvent motionEvent : mMotionEvents) { 60 motionEvent.recycle(); 61 } 62 63 mMotionEvents.clear(); 64 super.tearDown(); 65 } 66 67 68 @Test testSimpleTap_XSlop()69 public void testSimpleTap_XSlop() { 70 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 71 addMotionEvent(0, 1, MotionEvent.ACTION_UP, TOUCH_SLOP, 1); 72 73 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse(); 74 75 mMotionEvents.clear(); 76 77 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 78 addMotionEvent(0, 1, MotionEvent.ACTION_UP, -TOUCH_SLOP + 2, 1); 79 80 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse(); 81 82 } 83 84 @Test testSimpleTap_YSlop()85 public void testSimpleTap_YSlop() { 86 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 87 addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, TOUCH_SLOP); 88 89 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse(); 90 91 mMotionEvents.clear(); 92 93 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 94 addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, -TOUCH_SLOP + 2); 95 96 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse(); 97 } 98 99 100 @Test testFalseTap_XSlop()101 public void testFalseTap_XSlop() { 102 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 103 addMotionEvent(0, 1, MotionEvent.ACTION_UP, TOUCH_SLOP + 1, 1); 104 105 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue(); 106 107 mMotionEvents.clear(); 108 109 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 110 addMotionEvent(0, 1, MotionEvent.ACTION_UP, -TOUCH_SLOP - 1, 1); 111 112 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue(); 113 114 } 115 116 @Test testFalseTap_YSlop()117 public void testFalseTap_YSlop() { 118 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 119 addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, TOUCH_SLOP + 1); 120 121 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue(); 122 123 mMotionEvents.clear(); 124 125 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 126 addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, -TOUCH_SLOP - 1); 127 128 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue(); 129 } 130 131 @Test testLargeMovementFalses()132 public void testLargeMovementFalses() { 133 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 134 addMotionEvent(0, 1, MotionEvent.ACTION_MOVE, 1, TOUCH_SLOP + 1); 135 addMotionEvent(0, 2, MotionEvent.ACTION_UP, 1, 1); 136 137 assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue(); 138 } 139 140 @Test testDirectlySuppliedMotionEvents()141 public void testDirectlySuppliedMotionEvents() { 142 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 143 addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, 1); 144 145 assertThat(mClassifier.isTap(mMotionEvents, 0.5).isFalse()).isFalse(); 146 147 addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1); 148 addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, TOUCH_SLOP + 1); 149 150 assertThat(mClassifier.isTap(mMotionEvents, 0.5).isFalse()).isTrue(); 151 152 } 153 addMotionEvent(long downMs, long eventMs, int action, int x, int y)154 private void addMotionEvent(long downMs, long eventMs, int action, int x, int y) { 155 MotionEvent ev = MotionEvent.obtain(downMs, eventMs, action, x, y, 0); 156 mMotionEvents.add(ev); 157 when(mDataProvider.getRecentMotionEvents()).thenReturn(mMotionEvents); 158 } 159 } 160