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.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyDouble;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.Mockito.when;
25 
26 import android.testing.AndroidTestingRunner;
27 import android.view.MotionEvent;
28 import android.view.accessibility.AccessibilityManager;
29 
30 import androidx.test.filters.SmallTest;
31 
32 import com.android.internal.logging.MetricsLogger;
33 import com.android.internal.logging.testing.FakeMetricsLogger;
34 import com.android.systemui.SysuiTestCase;
35 import com.android.systemui.flags.FakeFeatureFlags;
36 import com.android.systemui.flags.Flags;
37 import com.android.systemui.plugins.FalsingManager;
38 import com.android.systemui.statusbar.policy.KeyguardStateController;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.Mock;
44 import org.mockito.MockitoAnnotations;
45 
46 import java.util.ArrayList;
47 import java.util.HashSet;
48 import java.util.List;
49 import java.util.Set;
50 
51 @SmallTest
52 @RunWith(AndroidTestingRunner.class)
53 public class BrightLineFalsingManagerTest extends SysuiTestCase {
54     private BrightLineFalsingManager mBrightLineFalsingManager;
55     @Mock
56     private FalsingDataProvider mFalsingDataProvider;
57     private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
58     private final Set<FalsingClassifier> mClassifiers = new HashSet<>();
59     @Mock
60     private SingleTapClassifier mSingleTapClassifier;
61     @Mock
62     private LongTapClassifier mLongTapClassifier;
63     @Mock
64     private DoubleTapClassifier mDoubleTapClassifier;
65     @Mock
66     private FalsingClassifier mClassifierA;
67     private final List<MotionEvent> mMotionEventList = new ArrayList<>();
68     @Mock
69     private HistoryTracker mHistoryTracker;
70     @Mock
71     private KeyguardStateController mKeyguardStateController;
72     @Mock
73     private AccessibilityManager mAccessibilityManager;
74 
75     private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
76     private final FalsingClassifier.Result mFalsedResult =
77             FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
78     private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
79 
80     @Before
setup()81     public void setup() {
82         MockitoAnnotations.initMocks(this);
83         when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
84                 .thenReturn(mFalsedResult);
85         when(mSingleTapClassifier.isTap(any(List.class), anyDouble())).thenReturn(mFalsedResult);
86         when(mLongTapClassifier.isTap(any(List.class), anyDouble())).thenReturn(mFalsedResult);
87         when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
88                 .thenReturn(mFalsedResult);
89         mClassifiers.add(mClassifierA);
90         when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
91         when(mKeyguardStateController.isShowing()).thenReturn(true);
92         when(mFalsingDataProvider.isUnfolded()).thenReturn(false);
93         mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
94                 mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier,
95                 mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
96                 mAccessibilityManager, false, mFakeFeatureFlags);
97         mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
98     }
99 
100     @Test
testA11yDisablesGesture()101     public void testA11yDisablesGesture() {
102         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
103         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
104         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
105     }
106 
107     @Test
testA11yDisablesTap()108     public void testA11yDisablesTap() {
109         assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
110         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
111         assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
112     }
113 
114 
115     @Test
testA11yDisablesLongTap()116     public void testA11yDisablesLongTap() {
117         assertThat(mBrightLineFalsingManager.isFalseLongTap(1)).isTrue();
118         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
119         assertThat(mBrightLineFalsingManager.isFalseLongTap(1)).isFalse();
120     }
121 
122     @Test
testA11yDisablesDoubleTap()123     public void testA11yDisablesDoubleTap() {
124         assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isTrue();
125         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
126         assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse();
127     }
128 
129     @Test
testIsProxNear_noProxEvents_defaultsToFalse()130     public void testIsProxNear_noProxEvents_defaultsToFalse() {
131         assertThat(mBrightLineFalsingManager.isProximityNear()).isFalse();
132     }
133 
134     @Test
testIsProxNear_receivesNearEvent()135     public void testIsProxNear_receivesNearEvent() {
136         mBrightLineFalsingManager.onProximityEvent(new FalsingManager.ProximityEvent() {
137             @Override
138             public boolean getCovered() {
139                 return true;
140             }
141 
142             @Override
143             public long getTimestampNs() {
144                 return 0;
145             }
146         });
147         assertThat(mBrightLineFalsingManager.isProximityNear()).isTrue();
148     }
149 
150     @Test
testIsProxNear_receivesNearAndThenFarEvent()151     public void testIsProxNear_receivesNearAndThenFarEvent() {
152         mBrightLineFalsingManager.onProximityEvent(new FalsingManager.ProximityEvent() {
153             @Override
154             public boolean getCovered() {
155                 return true;
156             }
157 
158             @Override
159             public long getTimestampNs() {
160                 return 0;
161             }
162         });
163         mBrightLineFalsingManager.onProximityEvent(new FalsingManager.ProximityEvent() {
164             @Override
165             public boolean getCovered() {
166                 return false;
167             }
168 
169             @Override
170             public long getTimestampNs() {
171                 return 5;
172             }
173         });
174         assertThat(mBrightLineFalsingManager.isProximityNear()).isFalse();
175     }
176 
177     @Test
testA11yAction()178     public void testA11yAction() {
179         assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
180         when(mFalsingDataProvider.isA11yAction()).thenReturn(true);
181         assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
182     }
183 
184     @Test
testSkipUnfolded()185     public void testSkipUnfolded() {
186         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
187         when(mFalsingDataProvider.isUnfolded()).thenReturn(true);
188         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
189     }
190 
191     @Test
testTrackpadGesture()192     public void testTrackpadGesture() {
193         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
194         when(mFalsingDataProvider.isFromTrackpad()).thenReturn(true);
195         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
196     }
197 }
198