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.Classifier.BRIGHTNESS_SLIDER;
20 import static com.android.systemui.classifier.Classifier.GENERIC;
21 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
22 
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import static org.mockito.Mockito.when;
26 
27 import android.testing.AndroidTestingRunner;
28 import android.view.MotionEvent;
29 
30 import androidx.test.filters.SmallTest;
31 
32 import com.android.systemui.plugins.FalsingManager;
33 import com.android.systemui.util.DeviceConfigProxyFake;
34 
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.mockito.Mock;
40 import org.mockito.MockitoAnnotations;
41 
42 @SmallTest
43 @RunWith(AndroidTestingRunner.class)
44 public class ProximityClassifierTest extends ClassifierTest {
45 
46     private static final long NS_PER_MS = 1000000;
47 
48     @Mock
49     private FalsingDataProvider mDataProvider;
50     @Mock
51     private DistanceClassifier mDistanceClassifier;
52     private FalsingClassifier mClassifier;
53 
54     private final FalsingClassifier.Result mFalsedResult =
55             FalsingClassifier.Result.falsed(1, getClass().getSimpleName() , "test");
56     private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
57 
58     @Before
setup()59     public void setup() {
60         super.setup();
61         MockitoAnnotations.initMocks(this);
62         when(mDistanceClassifier.isLongSwipe()).thenReturn(mFalsedResult);
63         mClassifier = new ProximityClassifier(
64                 mDistanceClassifier, mDataProvider, new DeviceConfigProxyFake());
65     }
66 
67     @After
tearDown()68     public void tearDown() {
69         super.tearDown();
70     }
71 
72     @Test
testPass_uncovered()73     public void testPass_uncovered() {
74         touchDown();
75         touchUp(10);
76         assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
77     }
78 
79     @Test
testPass_mostlyUncovered()80     public void testPass_mostlyUncovered() {
81         touchDown();
82         mClassifier.onProximityEvent(createSensorEvent(true, 1));
83         mClassifier.onProximityEvent(createSensorEvent(false, 2));
84         touchUp(20);
85         assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
86     }
87 
88     @Test
testPass_quickSettings()89     public void testPass_quickSettings() {
90         touchDown();
91         mClassifier.onProximityEvent(createSensorEvent(true, 1));
92         mClassifier.onProximityEvent(createSensorEvent(false, 11));
93         touchUp(10);
94         assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse()).isFalse();
95     }
96 
97     @Test
testPass_brightnessSlider()98     public void testPass_brightnessSlider() {
99         touchDown();
100         mClassifier.onProximityEvent(createSensorEvent(true, 1));
101         mClassifier.onProximityEvent(createSensorEvent(false, 11));
102         touchUp(10);
103         assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse())
104                 .isFalse();
105     }
106 
107     @Test
testFail_covered()108     public void testFail_covered() {
109         touchDown();
110         mClassifier.onProximityEvent(createSensorEvent(true, 1));
111         mClassifier.onProximityEvent(createSensorEvent(false, 11));
112         touchUp(10);
113         assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
114     }
115 
116     @Test
testFail_mostlyCovered()117     public void testFail_mostlyCovered() {
118         touchDown();
119         mClassifier.onProximityEvent(createSensorEvent(true, 1));
120         mClassifier.onProximityEvent(createSensorEvent(true, 95));
121         mClassifier.onProximityEvent(createSensorEvent(true, 96));
122         mClassifier.onProximityEvent(createSensorEvent(false, 100));
123         touchUp(100);
124         assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
125     }
126 
127     @Test
testPass_coveredWithLongSwipe()128     public void testPass_coveredWithLongSwipe() {
129         touchDown();
130         mClassifier.onProximityEvent(createSensorEvent(true, 1));
131         mClassifier.onProximityEvent(createSensorEvent(false, 11));
132         touchUp(10);
133         when(mDistanceClassifier.isLongSwipe()).thenReturn(mPassedResult);
134         assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
135     }
136 
touchDown()137     private void touchDown() {
138         MotionEvent motionEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0, 0, 0);
139         mClassifier.onTouchEvent(motionEvent);
140         motionEvent.recycle();
141     }
142 
touchUp(long duration)143     private void touchUp(long duration) {
144         MotionEvent motionEvent = MotionEvent.obtain(1, 1 + duration, MotionEvent.ACTION_UP, 0,
145                 100, 0);
146 
147         mClassifier.onTouchEvent(motionEvent);
148 
149         motionEvent.recycle();
150     }
151 
createSensorEvent(boolean covered, long timestampMs)152     private FalsingManager.ProximityEvent createSensorEvent(boolean covered, long timestampMs) {
153         return new FalsingManager.ProximityEvent() {
154             @Override
155             public boolean getCovered() {
156                 return covered;
157             }
158 
159             @Override
160             public long getTimestampNs() {
161                 return timestampMs * NS_PER_MS;
162             }
163         };
164     }
165 }
166